Ejemplo n.º 1
0
void gp2x_frontend_init(void)
{
	int ret;
        
	uint32_t display_width, display_height;
    
	VC_RECT_T dst_rect;
	VC_RECT_T src_rect;
    
	surface_width = 640;
	surface_height = 480;
    
	gp2x_screen8=0;
	gp2x_screen15=(unsigned short *) calloc(1, 640*480*2);
	
	graphics_get_display_size(0 /* LCD */, &display_width, &display_height);
    
	dispman_display = vc_dispmanx_display_open( 0 );
	assert( dispman_display != 0 );
        
	// Add border around bitmap for TV
	display_width -= options.display_border * 2;
	display_height -= options.display_border * 2;
    
	//Create two surfaces for flipping between
	//Make sure bitmap type matches the source for better performance
	uint32_t crap;
	resource0 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, 640, 480, &crap);
	resource1 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, 640, 480, &crap);
    
	vc_dispmanx_rect_set( &dst_rect, options.display_border, options.display_border,
                         display_width, display_height);
	vc_dispmanx_rect_set( &src_rect, 0, 0, 640 << 16, 480 << 16);
    
	//Make sure mame and background overlay the menu program
	dispman_update = vc_dispmanx_update_start( 0 );
    
	// create the 'window' element - based on the first buffer resource (resource0)
	dispman_element = vc_dispmanx_element_add(  dispman_update,
                                              dispman_display,
                                              1,
                                              &dst_rect,
                                              resource0,
                                              &src_rect,
                                              DISPMANX_PROTECTION_NONE,
                                              0,
                                              0,
                                              (DISPMANX_TRANSFORM_T) 0 );
    
	ret = vc_dispmanx_update_submit_sync( dispman_update );
    
	// setup swapping of double buffers
	cur_res = resource1;
	prev_res = resource0;
    
}
Ejemplo n.º 2
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_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 );
}
Ejemplo n.º 4
0
static void frontend_init(void)
{
  uint32_t display_width=0, display_height=0;

  VC_RECT_T dst_rect;
  VC_RECT_T src_rect;

  bcm_host_init();

  //initialise dispmanx display and resources
  fe_screen=(unsigned short *) calloc(1, 640*480*2);

  graphics_get_display_size(0 /* LCD */, &display_width, &display_height);

  fe_display = vc_dispmanx_display_open( 0 );

  //Create two surfaces for flipping between
  //Make sure bitmap type matches the source for better performance
  uint32_t crap;
  fe_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, 640, 480, &crap);

  vc_dispmanx_rect_set( &dst_rect, 0, 0, display_width, display_height);
  vc_dispmanx_rect_set( &src_rect, 0, 0, 640 << 16, 480 << 16);

  //Make sure mame and background overlay the menu program
  fe_update = vc_dispmanx_update_start( 0 );

  // create the 'window' element - based on the first buffer resource (resource0)
  fe_element = vc_dispmanx_element_add(  fe_update,
      fe_display, 1, &dst_rect, fe_resource, &src_rect,
      DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0 );

  vc_dispmanx_update_submit_sync( fe_update );
}
Ejemplo n.º 5
0
static void dispmanx_surface_setup(void *data, int width, int height, int pitch, float aspect,
   struct dispmanx_surface *surface)
{
   struct dispmanx_video *_dispvars = data;
   int i, dst_width, dst_height, dst_xpos, dst_ypos;

   /* Allocate memory for all the pages in each surface
    * and initialize variables inside each page's struct. */
   surface->pages = calloc(surface->numpages, sizeof(struct dispmanx_page));
   for (i = 0; i < surface->numpages; i++) {
      surface->pages[i].used = false;   
      surface->pages[i].dispvars = _dispvars;   
      surface->pages[i].page_used_mutex = slock_new(); 
   }

   /* Internal frame dimensions. Pitch is total pitch including info 
    * between scanlines */
   surface->width = width;
   surface->height = height;
   surface->pitch = pitch;
   surface->aspect = aspect;  
 
   /* The "visible" width obtained from the core pitch. We blit based on 
    * the "visible" width, for cores with things between scanlines. */
   int visible_width = pitch / surface->bpp;
 
   dst_width  = _dispvars->dispmanx_height * aspect;	
   dst_height = _dispvars->dispmanx_height;
   
   /* 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 (dst_width > _dispvars->dispmanx_width) 
      dst_width = _dispvars->dispmanx_width;
   
   dst_xpos = (_dispvars->dispmanx_width - dst_width) / 2;
   dst_ypos = (_dispvars->dispmanx_height - dst_height) / 2;

   /* We configure the rects now. */
   vc_dispmanx_rect_set(&surface->dst_rect, dst_xpos, dst_ypos, dst_width, dst_height);
   vc_dispmanx_rect_set(&surface->bmp_rect, 0, 0, width, height);	
   vc_dispmanx_rect_set(&surface->src_rect, 0, 0, width << 16, height << 16);	

   for (i = 0; i < surface->numpages; i++) {
      surface->pages[i].resource = 
         vc_dispmanx_resource_create(surface->pixformat, 
	 visible_width, height, &(_dispvars->vc_image_ptr));
   }
   /* Add element. */
   _dispvars->update = vc_dispmanx_update_start(0);

   surface->element = vc_dispmanx_element_add(
      _dispvars->update,_dispvars->display, surface->layer, 
      &surface->dst_rect, surface->pages[0].resource, 
      &surface->src_rect, DISPMANX_PROTECTION_NONE,
      &surface->alpha, 0, (DISPMANX_TRANSFORM_T)0);

   vc_dispmanx_update_submit_sync(_dispvars->update);		

   surface->setup = true;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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 );
}
Ejemplo n.º 8
0
		int Initialize()
		{
			fbfd = 0;
			fbp = 0;

			setlogmask(LOG_UPTO(LOG_DEBUG));
			openlog("fbcp", LOG_NDELAY | LOG_PID, LOG_USER);

			bcm_host_init();

			display = vc_dispmanx_display_open(0);
			if (!display) {
				syslog(LOG_ERR, "Unable to open primary display");
				return -1;
			}
			ret = vc_dispmanx_display_get_info(display, &display_info);
			if (ret) {
				syslog(LOG_ERR, "Unable to get primary display information");
				return -1;
			}
			syslog(LOG_INFO, "Primary display is %d x %d", display_info.width, display_info.height);


			fbfd = open("/dev/fb1", O_RDWR);
			if (!fbfd) {
				syslog(LOG_ERR, "Unable to open secondary display");
				return -1;
			}
			if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
				syslog(LOG_ERR, "Unable to get secondary display information");
				return -1;
			}
			if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
				syslog(LOG_ERR, "Unable to get secondary display information");
				return -1;
			}

			syslog(LOG_INFO, "Second display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

			screen_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, vinfo.xres, vinfo.yres, &image_prt);
			if (!screen_resource) {
				syslog(LOG_ERR, "Unable to create screen buffer");
				close(fbfd);
				vc_dispmanx_display_close(display);
				return -1;
			}

			fbp = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
			if (fbp <= 0) {
				syslog(LOG_ERR, "Unable to create mamory mapping");
				close(fbfd);
				ret = vc_dispmanx_resource_delete(screen_resource);
				vc_dispmanx_display_close(display);
				return -1;
			}

			vc_dispmanx_rect_set(&rect1, 0, 0, vinfo.xres, vinfo.yres);
			return 1;
		}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue)
{
  DISPMANX_DISPLAY_HANDLE_T display;
  DISPMANX_RESOURCE_HANDLE_T resource;
  VC_RECT_T rect;
  unsigned char *image = NULL;
  uint32_t vc_image_ptr;
  int stride;

  display = vc_dispmanx_display_open( 0 /*screen*/ );
  stride = ((width + 15) & ~15) * 4;
  image = new unsigned char [height * stride];

  if (image)
  {
    resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr );

    vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)0);

    vc_dispmanx_rect_set(&rect, 0, 0, width, height);
    vc_dispmanx_resource_read_data(resource, &rect, image, stride);
    vc_dispmanx_resource_delete( resource );
    vc_dispmanx_display_close(display );

    // we need to save in BGRA order so Swap RGBA -> BGRA
    if (swap_red_blue)
    {
      for (int y = 0; y < height; y++)
      {
        unsigned char *p = image + y * stride;
        for (int x = 0; x < width; x++, p+=4)
        {
          unsigned char t = p[0];
          p[0] = p[2];
          p[2] = t;
        }
      }
    }
    // assume we need to pack image if caller doesn't want stride
    if (!pstride && stride > width*4)
    {
      for (int y = 0; y < height; y++)
      {
        unsigned char *in  = image + y * stride;
        unsigned char *out = image + y * width * 4;
        memmove(out, in, width*4);
      }
    }
  }
  if (pstride)
    *pstride = stride;
  return image;
}
Ejemplo n.º 11
0
uint32_t allocate_and_set_vc_handle(gralloc_private_handle_t *private_handle) {
    uint32_t vc_handle = 0;
    DISPMANX_RESOURCE_HANDLE_T resource_handle = vc_dispmanx_resource_create(
            convert_android_to_vc_img_type(private_handle->pixel_format), private_handle->w, private_handle->h,
            &vc_handle);

    //vc_dispmanx_resource_create set vc_handle to 0
    //call to vc_dispmanx_resource_get_image_handle is needed
    vc_handle = vc_dispmanx_resource_get_image_handle(resource_handle);

    return vc_handle;
}
Ejemplo n.º 12
0
void save_snapshot(void)
{
  DISPMANX_DISPLAY_HANDLE_T display;
  DISPMANX_MODEINFO_T info;
  DISPMANX_RESOURCE_HANDLE_T resource;
  VC_IMAGE_TYPE_T type = VC_IMAGE_RGB888;
  VC_IMAGE_TRANSFORM_T transform = 0;
  VC_RECT_T rect;
  void *image;
  uint32_t vc_image_ptr;
  int ret;
  uint32_t screen = 0;

  fprintf(stderr,"\nWriting snapshot...\n");
  //fprintf(stderr,"Open display[%i]...\n", screen );
  display = vc_dispmanx_display_open( screen );

  ret = vc_dispmanx_display_get_info(display, &info);
  assert(ret == 0);
  //fprintf(stderr,"Display is %d x %d\n", info.width, info.height );

  image = calloc( 1, info.width * 3 * info.height );

  assert(image);

  resource = vc_dispmanx_resource_create(type, info.width, info.height,&vc_image_ptr);

  vc_dispmanx_snapshot(display, resource, transform);

  vc_dispmanx_rect_set(&rect, 0, 0, info.width, info.height);
  vc_dispmanx_resource_read_data(resource, &rect, image, info.width*3);

  char* home = getenv("HOME");
  char filename[1024];
  if (!home)
    home = "/tmp";

  snprintf(filename,sizeof(filename),"%s/pidvbip-%u.ppm",home,(unsigned int)time(NULL));
  FILE *fp = fopen(filename, "wb");
  fprintf(fp, "P6\n%d %d\n255\n", info.width, info.height);
  fwrite(image, info.width*3*info.height, 1, fp);
  fclose(fp);

  fprintf(stderr,"\nSnapshot written to %s\n",filename);

  ret = vc_dispmanx_resource_delete( resource );
  assert( ret == 0 );
  ret = vc_dispmanx_display_close(display );
  assert( ret == 0 );

  free(image);
}
Ejemplo n.º 13
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.");

}
int main(void)
{
    DISPMANX_DISPLAY_HANDLE_T   display;
    DISPMANX_MODEINFO_T         info;
    DISPMANX_RESOURCE_HANDLE_T  resource;
    VC_IMAGE_TYPE_T type = VC_IMAGE_RGB888;
    VC_IMAGE_TRANSFORM_T   transform = 0;
    VC_RECT_T         rect;

    void                       *image;
    uint32_t                    vc_image_ptr;

    int                   ret;

    uint32_t        screen = 0;

    bcm_host_init();

    printf("Open display[%i]...\n", screen );
    display = vc_dispmanx_display_open( screen );

    ret = vc_dispmanx_display_get_info(display, &info);
    assert(ret == 0);
    printf( "Display is %d x %d\n", info.width, info.height );

    image = calloc( 1, info.width * 3 * info.height );

    assert(image);

    resource = vc_dispmanx_resource_create( type,
                                                  info.width,
                                                  info.height,
                                                  &vc_image_ptr );

    vc_dispmanx_snapshot(display, resource, transform);

    vc_dispmanx_rect_set(&rect, 0, 0, info.width, info.height);
    vc_dispmanx_resource_read_data(resource, &rect, image, info.width*3); 

    FILE *fp = fopen("out.ppm", "wb");
    fprintf(fp, "P6\n%d %d\n255\n", info.width, info.height);
    fwrite(image, info.width*3*info.height, 1, fp);
    fclose(fp);

    ret = vc_dispmanx_resource_delete( resource );
    assert( ret == 0 );
    ret = vc_dispmanx_display_close(display );
    assert( ret == 0 );

    return 0;
}
Ejemplo n.º 15
0
void dispmanxtest() {
	DISPMANX_DISPLAY_HANDLE_T display;
	int ret;
	DISPMANX_MODEINFO_T displayinfo;
	DISPMANX_RESOURCE_HANDLE_T res;
	int width = 1024;
	int height = 576;
	uint32_t vc_image_ptr;
	DISPMANX_UPDATE_HANDLE_T update;
	VC_RECT_T dst_rect,src_rect;
	DISPMANX_ELEMENT_HANDLE_T element;

	
	bcm_host_init();
	display = vc_dispmanx_display_open(0);
	ret = vc_dispmanx_display_get_info( display, &displayinfo);
	assert(ret==0);
	printf("display is %dx%d\n",displayinfo.width,displayinfo.height);
	res = vc_dispmanx_resource_create(VC_IMAGE_YUV420,width,height,&vc_image_ptr);
	vc_image_ptr = vc_dispmanx_resource_get_image_handle(res);
	printf("vc_image_ptr %x\n",vc_image_ptr);
	assert(res);
	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,(displayinfo.height - height)/2,width-32,height);
	element = vc_dispmanx_element_add(update,display,2000,&dst_rect,res,&src_rect,DISPMANX_PROTECTION_NONE,NULL,NULL,DISPMANX_NO_ROTATE);
	ret = vc_dispmanx_update_submit_sync(update);
	assert(ret==0);
	uint8_t *rawfb = (uint8_t*)mapmem(vc_image_ptr,0x1000);
	for (int i=0; i<0x100; i++) {
		printf("%02x ",rawfb[i]);
	}
	printf("\n");
	unmapmem(rawfb,0x1000);
	puts("sleeping");
	sleep(10);
	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);
	ret = vc_dispmanx_resource_delete(res);
	assert(ret==0);
	ret = vc_dispmanx_display_close(display);
	assert(ret==0);
}
Ejemplo n.º 16
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;

}
Ejemplo n.º 17
0
Archivo: vout.c Proyecto: 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;
}
Ejemplo n.º 18
0
Archivo: RBP.cpp Proyecto: Cygne/xbmc
unsigned char *CRBP::CaptureDisplay(int width, int height, int *pstride, bool swap_red_blue, bool video_only)
{
  DISPMANX_DISPLAY_HANDLE_T display;
  DISPMANX_RESOURCE_HANDLE_T resource;
  VC_RECT_T rect;
  unsigned char *image = NULL;
  uint32_t vc_image_ptr;
  int stride;
  uint32_t flags = 0;

  if (video_only)
    flags |= DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL;
  if (swap_red_blue)
    flags |= DISPMANX_SNAPSHOT_SWAP_RED_BLUE;
  if (!pstride)
    flags |= DISPMANX_SNAPSHOT_PACK;

  display = vc_dispmanx_display_open( 0 /*screen*/ );
  stride = ((width + 15) & ~15) * 4;
  image = new unsigned char [height * stride];

  if (image)
  {
    resource = vc_dispmanx_resource_create( VC_IMAGE_RGBA32, width, height, &vc_image_ptr );

    vc_dispmanx_snapshot(display, resource, (DISPMANX_TRANSFORM_T)flags);

    vc_dispmanx_rect_set(&rect, 0, 0, width, height);
    vc_dispmanx_resource_read_data(resource, &rect, image, stride);
    vc_dispmanx_resource_delete( resource );
    vc_dispmanx_display_close(display );
  }
  if (pstride)
    *pstride = stride;
  return image;
}
Ejemplo n.º 19
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;
    }
  }
}
Ejemplo n.º 20
0
// Initialize the OpenGL library
void initGL(int width, int height) {

    #ifdef PLATFORM_RPI
    // Start clock
    gettimeofday(&tv, NULL);
    timeStart = (unsigned long long)(tv.tv_sec) * 1000 +
                (unsigned long long)(tv.tv_usec) / 1000; 

    // Start OpenGL ES
    bcm_host_init();

    // Clear application state
    EGLBoolean result;
    EGLint num_config;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        // EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_DEPTH_SIZE, 16,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    EGLConfig config;

    // get an EGL display connection
    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(display!=EGL_NO_DISPLAY);
    check();

    // initialize the EGL display connection
    result = eglInitialize(display, NULL, NULL);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);
    check();

    // create an EGL rendering context
    context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
    assert(context != EGL_NO_CONTEXT);
    check();
    
    static EGL_DISPMANX_WINDOW_T nativeviewport;

    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    uint32_t dest_image_handle;
    uint32_t screen_width = width;
    uint32_t screen_height = height;

    //  Initially the viewport is for all the screen
    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = screen_width;
    dst_rect.height = screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = screen_width << 16;
    src_rect.height = screen_height << 16;

    DISPMANX_RESOURCE_HANDLE_T dispman_resource;
    dispman_resource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, screen_width, screen_height, &dest_image_handle);
    dispman_display = vc_dispmanx_display_open_offscreen(dispman_resource, DISPMANX_NO_ROTATE);
    // dispman_display = vc_dispmanx_display_open( 0 /* LCD */);

    DISPMANX_UPDATE_HANDLE_T dispman_update;
    dispman_update = vc_dispmanx_update_start(0);

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    dispman_element = vc_dispmanx_element_add( dispman_update, dispman_display,
                                                0/*layer*/, &dst_rect, 0/*src*/,
                                                &src_rect, DISPMANX_PROTECTION_NONE, 
                                                0 /*alpha*/, 0/*clamp*/, (DISPMANX_TRANSFORM_T)0/*transform*/);

    nativeviewport.element = dispman_element;
    nativeviewport.width = screen_width;
    nativeviewport.height = screen_height;
    vc_dispmanx_update_submit_sync(dispman_update);
    check();

    surface = eglCreateWindowSurface(display, config, &nativeviewport, NULL);
    assert(surface != EGL_NO_SURFACE);
    check();

    // connect the context to the surface
    result = eglMakeCurrent(display, surface, surface, context);
    assert(EGL_FALSE != result);
    check();

    glViewport(0.0f, 0.0f, (float)screen_width, (float)screen_height);
    check();

    #else
    //  ---------------------------------------- using GLFW
    //
    if (!glfwInit()) {
        return;
    }

    glfwWindowHint(GLFW_SAMPLES, 2);
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
    window = glfwCreateWindow(width, height, "", NULL, NULL);
    if (!window) {
        glfwTerminate();
    }

    // Make the main_window's context current
    glfwMakeContextCurrent(window);
    #endif
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
	DISPMANX_DISPLAY_HANDLE_T main_display_handle;
	DISPMANX_RESOURCE_HANDLE_T screen_resource_handle;
	
	VC_RECT_T rectangle;
	
	int ret;
	uint32_t image_prt;
	uint16_t image[2][ PICTURE_PIXELS ];
	uint32_t current_frame = 0, old_frame=1;
	uint32_t i, x, y, start, end, count;
	uint16_t *p_current_frame, *p_old_frame, *p_start;
		
	bcm_host_init();
	
	if ( !bcm2835_init() )
	return ( -1 );
	
	TFT_init_board();
	
	TFT_hard_reset();
	
	RAIO_init();

	//clear old image 
	p_old_frame     = &image[ old_frame ][0];
	for(x=0; x<76800; x++)
	{
		*p_old_frame++ = 0x1111;
	}
	
	
	// open main framebuffer device
	main_display_handle = vc_dispmanx_display_open( 0 );
    if ( !main_display_handle )
    {
        printf("\n Unable to open primary display");
        return( -1 );
    }
    
    // now build up the shadow area for RAIO
    screen_resource_handle = vc_dispmanx_resource_create( VC_IMAGE_RGB565, DISPLAY_WIDTH, DISPLAY_HEIGHT, &image_prt );       
    if ( !screen_resource_handle )
    {
        printf("\n Unable to create screen buffer");
        vc_dispmanx_display_close( main_display_handle );
        return ( -1 );
    }

	vc_dispmanx_rect_set( &rectangle, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT );    
    
    while( 1 )
    {    
		ret = vc_dispmanx_snapshot( main_display_handle, screen_resource_handle, DISPMANX_NO_ROTATE );  
    
		vc_dispmanx_resource_read_data( screen_resource_handle, &rectangle, &image[ current_frame ][0], DISPLAY_WIDTH*2 ); 

		
		i=0;
		p_current_frame = &image[ current_frame ][ 0 ];
		p_old_frame     = &image[ old_frame ][ 0 ];	
		
		while (i<PICTURE_PIXELS)
		{		
			while (( *p_current_frame == *p_old_frame) && (i<PICTURE_PIXELS) )
			{
				p_current_frame++;
				p_old_frame++;
				i = i+1;
			}
			p_start = p_current_frame;
			start = i;
			
			
			while (( *p_current_frame != *p_old_frame) && (i<PICTURE_PIXELS) )
			{
				p_current_frame++;
				p_old_frame++;
				i = i+1;
			}
			count = i - start;
			
			y=start/DISPLAY_WIDTH;
			x=start-y*DISPLAY_WIDTH;
			RAIO_set_cursor( x, y );
			RAIO_Write_Picture( p_start, count );				
		}
		
		
		old_frame = current_frame;
		if ( current_frame == 0 )
			current_frame = 1;
		else
			current_frame = 0;
			
			
		// 100ms -> 10 fps
		usleep( 100 * 1000 );
	
	}


	return ( 0 );
}
Ejemplo n.º 22
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));
}
Ejemplo n.º 23
0
static bool dispmanx_setup_scale(void *data, unsigned width,
      unsigned height, unsigned pitch)
{
	int i, dst_ypos;
	VC_DISPMANX_ALPHA_T layerAlpha;    
  	struct dispmanx_video *_dispvars = data;

   if (!_dispvars)
      return false;

	/* Since internal frame resolution seems to have changed, we change the 
    * internal frame resolution in use, and call dispmanx_setup_scale()
    * again to set the rects, etc. */
	_dispvars->width = width;
	_dispvars->height = height;

	/* Total pitch, including things the cores 
    * render between "visible" scanlines. */
	_dispvars->pitch = pitch;

	/* The "visible" width obtained from the core pitch. */
	_dispvars->visible_width = pitch / _dispvars->bytes_per_pixel;

	dispmanx_free_main_resources(_dispvars);
	vc_dispmanx_display_get_info(_dispvars->display, &(_dispvars->amode));

	// We choose the pixel format depending on the bpp of the frame.
	switch (_dispvars->bytes_per_pixel)
   {
      case 2:	
         _dispvars->pixFormat = VC_IMAGE_RGB565;	       
         break;
      case 4:	
         _dispvars->pixFormat = VC_IMAGE_XRGB8888;	       
         break;
      default:
         RARCH_ERR("video_dispmanx: wrong pixel format\n");
         return NULL;
   }	

	/* Transparency disabled */
	layerAlpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
	layerAlpha.opacity = 255;
	layerAlpha.mask = 0;
	_dispvars->alpha = &layerAlpha;	

  	switch (g_settings.video.aspect_ratio_idx)
   {
      case ASPECT_RATIO_4_3: 
         _dispvars->aspect = (float)4 / (float)3;
         break;
      case ASPECT_RATIO_16_9: 
         _dispvars->aspect = (float)16 / (float)9;
         break;
      case ASPECT_RATIO_16_10: 
         _dispvars->aspect = (float)16 / (float)10;
         break;
      case ASPECT_RATIO_16_15: 
         _dispvars->aspect = (float)16 / (float)15;
         break;
      case ASPECT_RATIO_CORE: 
         _dispvars->aspect = (float)_dispvars->width / (float)_dispvars->height;
         break;
      default: 
         _dispvars->aspect = (float)_dispvars->width / (float)_dispvars->height;
         break;
   }    

	int 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->dstRect), dst_ypos, 0, 
	   	dst_width, _dispvars->amode.height);
	
	/* We configure the rects now. */
	vc_dispmanx_rect_set(&(_dispvars->bmpRect), 0, 0, _dispvars->width, _dispvars->height);	
	vc_dispmanx_rect_set(&(_dispvars->srcRect), 0, 0, _dispvars->width << 16, _dispvars->height << 16);	

	/* We create as many resources as pages */
	for (i = 0; i < NUMPAGES; i++)
		_dispvars->resources[i] = vc_dispmanx_resource_create(_dispvars->pixFormat, 
			_dispvars->visible_width, _dispvars->height, &(_dispvars->vcImagePtr));

	/* Add element. */
	_dispvars->update = vc_dispmanx_update_start(0);
	
	_dispvars->element = vc_dispmanx_element_add(_dispvars->update, _dispvars->display, 0,
		&(_dispvars->dstRect), _dispvars->resources[0], &(_dispvars->srcRect), 
		DISPMANX_PROTECTION_NONE, _dispvars->alpha, 0, (DISPMANX_TRANSFORM_T)0);
	
	vc_dispmanx_update_submit_sync(_dispvars->update);		

	return true;
}
static SDL_Surface *DISPMANX_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
//MAC Recuerda que aqui­,originalmente, nos llegaban las dimensiones de un modo de video
// aproximado en SDL_Video.c de entre los modos de video disponibles. AHORA YA NO.
//Ahora lo que hacemos es que nos lleguen directamente la altura y anchura del modo 
//en el que quiere correr la aplicacion, 
//Luego se escala ese modo, de cuanta menos resolucion mejor, (ya que hay
//que hacer una escritura de ram a grafica en la funcion FlipHWScreen), al modo fisico, que
//es en realidad el unico modo grafico que existe, el modo en que hemos arrancado.
//Esto explica por que creamos el plano de overlay a parte, 
//ya que cuando SDL_Video.c llama a SetVideoMode aun no se tienen listos los 
//offsets horizontal y vertical donde empieza el modo de video pequenio 
//(el modo en que corre la app internamente) sobre el grande (el modo fisico).
	
	//Si nos pasan width=0 y height=0, interpreto que el programa no quiere video sino
	//que solo necesita entrar en modo grafico, asi que salto alli:
	if ((width == 0) | (height == 0)) goto go_video_console;	

	//MAC Inicializamos el SOC (bcm_host_init) SOLO si no hemos pasado antes por aqui­. Lo mismo con el fondo.
	//Si ya hemos pasado antes, hacemos limpieza, pero dejamos el fondo sin tocar.
	if (dispvars->pixmem != NULL){
		//Hacemos limpieza de resources, pero dejamos el fondo. No hay problema porque solo lo ponemos
		//si no hemos pasado por aqui antes.
		DISPMANX_FreeResources();	
	}
	else {
    		uint32_t screen = 0;
		
		bcm_host_init();
		
		//MAC Abrimos el display dispmanx
		printf("Dispmanx: Opening display %i\n", screen );
        	dispvars->display = vc_dispmanx_display_open( screen );

		//MAC Recuperamos algunos datos de la configuracion del buffer actual
		vc_dispmanx_display_get_info( dispvars->display, &(dispvars->amode));
		printf( "Dispmanx: Physical video mode is %d x %d\n", 
		dispvars->amode.width, dispvars->amode.height );
		
		//Ponemos el element de fondo negro tanto si se respeta el ratio como si no, 
		//porque si no, se nos vera­a la consola al cambiar de resolucion durante el programa.
		DISPMANX_BlankBackground();
	}	
	


	//-------Bloque de lista de resoluciones, originalmente en VideoInit--------------
	//Para la aplicacion SDL, el unico modo de video disponible va a ser siempre el que pida. 
	
	DISPMANX_AddMode(this, width, height, (((bpp+7)/8)-1));

	//---------------------------------------------------------------------------------	
	
	Uint32 Rmask;
	Uint32 Gmask;
	Uint32 Bmask;
	
	//dispvars->pitch = width * ((bpp+7) /8);

	//MAC Establecemos el pitch en funcion del bpp deseado
        //Lo alineamos a 16 porque es el aligment interno de dispmanx(en ejemp)
	dispvars->bits_per_pixel = bpp;	
        dispvars->pitch = ( ALIGN_UP( width, 16 ) * (bpp/8) );
        //Alineamos la atura a 16 por el mismo motivo (ver ejemplo hello_disp)
        height = ALIGN_UP( height, 16);

	switch (bpp){
	   case 8:
		dispvars->pix_format = VC_IMAGE_8BPP;	       
		break;
	   
	   case 16:
		dispvars->pix_format = VC_IMAGE_RGB565;	       
		break;

	   case 32:
		dispvars->pix_format = VC_IMAGE_XRGB8888;	       
	        break;
           
           default:
	      printf ("\n[ERROR] - wrong bpp: %d\n",bpp);
	      return (NULL);
	}	
	    	
	//MAC blah 
	this->UpdateRects = DISPMANX_DirectUpdate;

	printf ("\nUsing internal program mode: %d x %d %d bpp", 
		width, height, dispvars->bits_per_pixel);	

	//MAC Por ahora en DISPMANX usamos el mismo modo q ya esta establecido
	printf ("\nUsing physical mode: %d x %d %d bpp",
		dispvars->amode.width, dispvars->amode.height,
		dispvars->bits_per_pixel);
	
	//-----------------------------------------------------------------------------
	//Esta parte no es fundamental, solo sirve para conservar el ratio del juego.
	//Si no se hace y simplemente quitas estas lineas, se estira al modo fisico y ya, 
	//quedando la imagen deformada si es de 4:3 en una tele de 16:9, que es lo que pasaba antes.	
	//Simplemente hallamos ese ratio y con el hallamos la nueva anchura, considerando
	//como altura la maxima fisica que tenemos establecida, o sea, la altura del modo fisico establecido. 
	//Tambien se calcula la posicion horizontal en que debe empezar el rect de destino (dst_ypos), 
	//para que no quede pegado a la parte izquierda de la pantalla al ser menor que la resolucion fisica, que
	//obviamente no cambia. 
	//Queda obsoleto si cambiamos la resolucion a una que tenga el mismo ratio que el modo original del juego.
	
	dispvars->ignore_ratio = (int) SDL_getenv("SDL_DISPMANX_IGNORE_RATIO");

	if (dispvars->ignore_ratio)
		vc_dispmanx_rect_set( &(dispvars->dst_rect), 0, 0, 
	   		dispvars->amode.width , dispvars->amode.height );
	else {
		float orig_ratio = ((float)width / (float)height); 
		int dst_width = dispvars->amode.height * orig_ratio;	
		
		//Si la anchura de la imagen escalada nos sale mayor que el ancho fisico de pantalla,
		//mantenemos el ancho fisico de pantalla como anchura maxima.
		if (dst_width > dispvars->amode.width) dst_width = dispvars->amode.width;

		int dst_ypos  = (dispvars->amode.width - dst_width) / 2; 
		printf ("\nUsing proportion ratio: %d / %d = %f", width, height, orig_ratio);
		printf ("\nProgram rect, respecting original ratio: %d x %d \n", 
		dst_width, dispvars->amode.height);

		vc_dispmanx_rect_set( &(dispvars->dst_rect), dst_ypos, 0, 
	   		dst_width , dispvars->amode.height );
			
	}

	//---------------------------Dejamos configurados los rects---------------------
	//Recuerda que los rects NO contienen ninguna informacion visual, solo son tamanio, rectangulos
	//descritos para que los entiendan las funciones vc, solo tamanios de areas.
	//
	//bmp_rect: se usa solo para el volcado del buffer en RAM al resource que toque. Define el tamanio
	//del area a copiar de RAM (pixmem) al resource (dispmam->resources[]) usando write_data(), por
	//eso, y para acabarlo de entender del todo, su altura y anchura son las internas del juego, width y height.
	//
	//src_rect y dst_rect: se usan porque un element necesita dos rects definidos: src_rect es el tamanio del area
	//de entrada,o sea, el tamanio con el que clipeamos la imagen de origen, y dst_rect es el tamanio del area de
	//salida, o sea, el tamanio con que se vera, escalada por hardware, en el element.
	//
	//Por todo esto, src_rect tendra generalmente la altura y anchura de la imagen original, o dicho de otro
	//modo la altura y anchura que usa el juego internamente (width << 16 y height << 16 por algun rollo de
	//tamanio de variable), y dst_rect tendra las dimensiones del area de pantalla a la que queremos escalar
	//esa imagen: si le damos las dimensiones fisicas totales de la pantalla, escalara sin respetar el ratio.   
	//Asi­que lo he corregido manteniendo la altura maxima de la pantalla fisica, y calculando la anchura
	//a partir de dicha altura y el ratio de la imagen (de la resolucion del juego) original.
	//
	//Debes pensar siempre de la siguiente manera: un element, que es como un cristal-lupa, un resource 
	//(aunque tengas dos, en un momento dado el element solo tiene uno) que es como la imagen original,
	//muy pequenita al fondo, y un "embudo", cuyo tamanio del extremo inferior pegado a la imagen original 
	//es de tamanio src_rect, y cuyo tamanio del extremo superior, pegado al element, es de tamanio dst_rect.
	
	vc_dispmanx_rect_set (&(dispvars->bmp_rect), 0, 0, 
	   width, height);	
	
	vc_dispmanx_rect_set (&(dispvars->src_rect), 0, 0, 
	   width << 16, height << 16);	

	//------------------------------------------------------------------------------
	
	//MAC Establecemos alpha. Para transparencia descomentar flags con or.
	VC_DISPMANX_ALPHA_T layerAlpha;
	/*layerAlpha.flags = (DISPMANX_FLAGS_ALPHA_FROM_SOURCE | 
           DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS);*/
	layerAlpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
	layerAlpha.opacity = 255;
	layerAlpha.mask	   = 0;
	dispvars->alpha = &layerAlpha;
	
	//MAC Creo los resources. Me hacen falta dos para el double buffering
	dispvars->resources[0] = vc_dispmanx_resource_create( 
	   dispvars->pix_format, width, height, 
	   &(dispvars->vc_image_ptr) );
	
	dispvars->resources[1] = vc_dispmanx_resource_create( 
	   dispvars->pix_format, width, height,
	   &(dispvars->vc_image_ptr) );
	
	//Reservo memoria para el array de pixles en RAM 
    	dispvars->pixmem = calloc( 1, dispvars->pitch * height);
    	//dispvars->pixmem=malloc ( dispvars->pitch * dispvars->amode.height );

	//MAC Esta llamada a ReallocFormat es lo que impedia­a ver algo...
	Rmask = 0;
	Gmask = 0;
	Bmask = 0;
	if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
		return(NULL);
	}
	
	//Preparamos SDL para trabajar sobre el nuevo framebuffer

	//No queremos HWSURFACEs por la manera en que funciona nuestro backend, ya que la app solo
	//debe conocer el buffer en RAM para que las actualizaciones no sean bloqueantes.
	//TAMPOCO queremos DOUBLEBUFFER: realmente piensa lo que estas haciendo: actualizas la 
	//superficie de video, que esta en la RAM, copias a VRAM y, saltandote las normas del API,
	//esperas a evento de vsync para hacer el buffer swapping. Asi­ que la app NO SABE NADA de 
	//double buffering ni debe saberlo. UpdateRect() debe hacer lo que antes hacia­a FlipHWSurface,
	//ya que de cara a la APP, solo hay una actualizacion del buffer de dibujado, NO de pantalla,
	//ya que carecemos de acceso directo a la VRAM.
	//Permitimos HWPALETTEs, cosa que solo se activa si el juego pide un modo de 8bpp porque,
	//tanto si conseguimos modificar la paleta por hard como si tenemos que indexar los valores
	//como estamos haciendo hasta ahora emulando asi la paleta, nos interesa que los juegos
	//entren en SetColors(), y sin paleta por hardware no entran.
	
	current->flags |= SDL_FULLSCREEN;	
	if (flags & SDL_DOUBLEBUF){
	   current->flags &= ~SDL_DOUBLEBUF;	
	}
	if (flags & SDL_HWSURFACE){
	   current->flags &= ~SDL_HWSURFACE;
	   current->flags |= SDL_SWSURFACE;
	}	
	if (flags & SDL_HWPALETTE)
	   current->flags |= SDL_HWPALETTE;	
	
	current->w = width;
	current->h = height;

	current->pitch  = dispvars->pitch;
	current->pixels = dispvars->pixmem;
	
	//DISPMANX_FreeHWSurfaces(this);
	//DISPMANX_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);
	
	//this->screen = current;
	//this->screen = NULL;

	//Aniadimos el element.
	dispvars->update = vc_dispmanx_update_start( 0 );
	
	dispvars->element = vc_dispmanx_element_add( dispvars->update, 
	   dispvars->display, 0 /*layer*/, &(dispvars->dst_rect), 	   
	   dispvars->resources[flip_page], &(dispvars->src_rect), 
	   DISPMANX_PROTECTION_NONE, dispvars->alpha, 0 /*clamp*/, 
	   /*VC_IMAGE_ROT0*/ 0 );
	
	vc_dispmanx_update_submit_sync( dispvars->update );		
	
	/* We're done */
	//MAC Disable graphics 1
	//Aqui ponemos la terminal en modo grafico. Ya no se imprimiran mas mensajes en la consola a partir de aqui. 
	go_video_console:
	if ( DISPMANX_EnterGraphicsMode(this) < 0 )
        	return(NULL);

	
	return(current);
}
Ejemplo n.º 25
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. */
}
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);
}
static jboolean fbDispmanRobotScreenCapture(jint x, jint y,
                                            jint width, jint height,
                                            jint *pixels) {
    FILE *fb;
    unsigned int *pixelBuffer = NULL;
    unsigned char *pixelBufferPtr = NULL;
    unsigned char *dst = (unsigned char *) pixels;
    int i = 0;
    int fbFileHandle;
    struct fb_var_screeninfo screenInfo;
    unsigned int dstByteStride = width * 4;
    VC_IMAGE_TRANSFORM_T transform = 0;
    DISPMANX_RESOURCE_HANDLE_T resource = 0;
    DISPMANX_DISPLAY_HANDLE_T display = 0;
    DISPMANX_RESOURCE_HANDLE_T screenResource = 0;
    uint32_t imagePtr;
    int rc;

    GLASS_LOG_FINE("Capture %i,%i+%ix%i", x, y, width, height);

    if (width < 1 || height < 1) {
        GLASS_LOG_SEVERE("Failed. width/height values must be at least = 1");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("open(%s, O_RDONLY)", FB_DEVICE);
    fbFileHandle = open(FB_DEVICE, O_RDONLY);
    if (fbFileHandle < 0) {
        GLASS_LOG_SEVERE("Cannot open framebuffer");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("ioctl(%s, FBIOGET_VSCREENINFO)", FB_DEVICE);
    if (ioctl(fbFileHandle, FBIOGET_VSCREENINFO, &screenInfo)) {
        GLASS_LOG_SEVERE("Cannot get screen info");
        GLASS_LOG_FINE("close(%s)", FB_DEVICE);
        close(fbFileHandle);
        return JNI_FALSE;
    }
    GLASS_LOG_FINE("Read screen info: res=%ix%i, offset=%ix%i",
                   screenInfo.xres, screenInfo.yres,
                   screenInfo.xoffset, screenInfo.yoffset);
    GLASS_LOG_FINE("close(%s)", FB_DEVICE);
    close(fbFileHandle);

    VC_RECT_T pixelRect = { 0, 0, screenInfo.xres, screenInfo.yres };

    int pixelBufferLength = screenInfo.xres * screenInfo.yres * 4;
    pixelBuffer = (unsigned int *) malloc(pixelBufferLength);
    pixelBufferPtr = (unsigned char *) pixelBuffer;

    if (pixelBuffer == NULL) {
        printf("Failed to allocate temporary pixel buffer\n");
        return JNI_FALSE;
    }

    GLASS_LOG_FINE("fopen(%s, \"r\") to read %ix%i pixels at bit depth %i\n",
                   FB_DEVICE, width, height, screenInfo.bits_per_pixel);

    display = vc_dispmanx_display_open(0 /* LCD */);
    if (display == 0) {
        fprintf(stderr, "fbRobotScreenCapture: Dispman: Cannot open display\n");
        free(pixelBuffer);
        return JNI_FALSE;
    }

    // create the resource for the snapshot
    screenResource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, screenInfo.xres, screenInfo.yres, &imagePtr);
    if (!screenResource) {
        fprintf(stderr, "fbRobotScreenCapture: Cannot create resource\n");
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_snapshot(display, screenResource, transform);
    rc = 0;
    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: snapshot failed\n");
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_resource_read_data(screenResource, &pixelRect, pixelBuffer, screenInfo.xres * 4);

    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: Cannot read pixels %d\n", rc);
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }

    rc = vc_dispmanx_resource_delete(screenResource);
    if (rc) {
        fprintf(stderr, "fbRobotScreenCapture: failed to free buffer %d\n", rc);
        vc_dispmanx_display_close(display);
        free(pixelBuffer);
        return JNI_FALSE;
    }
    screenResource = 0;

    if (x < 0) {
        pixelBuffer += -x;
        width += x;
        x = 0;
    }
    if (y < 0) {
        pixelBuffer += -y * (int)screenInfo.xres;
        height += y;
        y = 0;
    }

    int widthLimit = width;
    int heightLimit = height;

    // Required height is larger than screen's height
    if ((int) screenInfo.yres < height) {
        heightLimit = (int) screenInfo.yres;
    }
    // Required width is larger than screen's width
    if ((int) screenInfo.xres < width) {
        widthLimit = (int) screenInfo.xres;
    }
    // Required height is out of range
    if (((int) screenInfo.yres - y) < height) {
        heightLimit = (int) screenInfo.yres - y;
    }
    // Required width is out of range
    if (((int) screenInfo.xres - x) < width) {
        widthLimit = (int) screenInfo.xres - x;
    }

    if (widthLimit > 0 && heightLimit > 0) {
        // copy the relevant portion of the screen to the supplied pixel array
        int offset = y * screenInfo.xres * 4 + x * 4;
        for (i = 0; i < heightLimit; i++) {
            memcpy(dst + i * dstByteStride, pixelBufferPtr + offset, widthLimit * 4);
            offset += screenInfo.xres * 4;
        }
    } else {
        GLASS_LOG_SEVERE("Failed to take a snapshot, some of parameters are illegal");
        free(pixelBuffer);
        return JNI_FALSE;
    }

    vc_dispmanx_display_close(display);
    free(pixelBuffer);
    return JNI_TRUE;
}
Ejemplo n.º 28
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
}
Ejemplo n.º 29
0
int process() {
    DISPMANX_DISPLAY_HANDLE_T display;
    DISPMANX_MODEINFO_T display_info;
    DISPMANX_RESOURCE_HANDLE_T screen_resource;
    VC_IMAGE_TRANSFORM_T transform;
    uint32_t image_prt;
    VC_RECT_T rect1;
    int ret;
    int fbfd = 0;
    char *fbp = 0;

    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;


    bcm_host_init();

    display = vc_dispmanx_display_open(0);
    if (!display) {
        syslog(LOG_ERR, "Unable to open primary display");
        return -1;
    }
    ret = vc_dispmanx_display_get_info(display, &display_info);
    if (ret) {
        syslog(LOG_ERR, "Unable to get primary display information");
        return -1;
    }
    syslog(LOG_INFO, "Primary display is %d x %d", display_info.width, display_info.height);


    fbfd = open("/dev/fb1", O_RDWR);
    if (!fbfd) {
        syslog(LOG_ERR, "Unable to open secondary display");
        return -1;
    }
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
        syslog(LOG_ERR, "Unable to get secondary display information");
        return -1;
    }
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
        syslog(LOG_ERR, "Unable to get secondary display information");
        return -1;
    }

    syslog(LOG_INFO, "Second display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    screen_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, vinfo.xres, vinfo.yres, &image_prt);
    if (!screen_resource) {
        syslog(LOG_ERR, "Unable to create screen buffer");
        close(fbfd);
        vc_dispmanx_display_close(display);
        return -1;
    }

    fbp = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
    if (fbp <= 0) {
        syslog(LOG_ERR, "Unable to create mamory mapping");
        close(fbfd);
        ret = vc_dispmanx_resource_delete(screen_resource);
        vc_dispmanx_display_close(display);
        return -1;
    }

    vc_dispmanx_rect_set(&rect1, 0, 0, vinfo.xres, vinfo.yres);

    while (1) {
        ret = vc_dispmanx_snapshot(display, screen_resource, 0);
        vc_dispmanx_resource_read_data(screen_resource, &rect1, fbp, vinfo.xres * vinfo.bits_per_pixel / 8);
        usleep(25 * 1000);
    }

    munmap(fbp, finfo.smem_len);
    close(fbfd);
    ret = vc_dispmanx_resource_delete(screen_resource);
    vc_dispmanx_display_close(display);
}
Ejemplo n.º 30
0
void pi_setvideo_mode(int width, int height) {

    uint32_t display_width, display_height;
    uint32_t display_x = 0, display_y = 0;
    float display_ratio, game_ratio;

    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    surface_width = width;
    surface_height = height;

    VideoBuffer = (unsigned short *) calloc(1, width * height * 4);

    // get an EGL display connection
    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(display != EGL_NO_DISPLAY);

    // initialize the EGL display connection
    EGLBoolean result = eglInitialize(display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    EGLint num_config;
    EGLConfig config;
    static const EGLint attribute_list[] =
            {
                    EGL_RED_SIZE, 8,
                    EGL_GREEN_SIZE, 8,
                    EGL_BLUE_SIZE, 8,
                    EGL_ALPHA_SIZE, 8,
                    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                    EGL_NONE
            };
    result = eglChooseConfig(display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    static const EGLint context_attributes[] =
            {
                    EGL_CONTEXT_CLIENT_VERSION, 2,
                    EGL_NONE
            };
    context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
    assert(context != EGL_NO_CONTEXT);

    // create an EGL window surface
    int32_t success = graphics_get_display_size(0, &display_width, &display_height);
    assert(success >= 0);

    display_adj_width = display_width - (config_options.option_display_border * 2);
    display_adj_height = display_height - (config_options.option_display_border * 2);

    if (config_options.display_smooth_stretch) {
        //We use the dispmanx scaler to smooth stretch the display
        //so GLES2 doesn't have to handle the performance intensive postprocessing

        uint32_t sx, sy;

        // Work out the position and size on the display
        display_ratio = (float) display_width / (float) display_height;
        game_ratio = (float) width / (float) height;

        display_x = sx = display_adj_width;
        display_y = sy = display_adj_height;

        if (config_options.maintain_aspect_ratio || game_ratio < 1) {
            if (game_ratio > display_ratio)
                sy = (float) display_adj_width / (float) game_ratio;
            else
                sx = (float) display_adj_height * (float) game_ratio;
        }

        // Centre bitmap on screen
        display_x = (display_x - sx) / 2;
        display_y = (display_y - sy) / 2;

        vc_dispmanx_rect_set(&dst_rect,
                             display_x + config_options.option_display_border,
                             display_y + config_options.option_display_border,
                             sx, sy);
    }
    else
        vc_dispmanx_rect_set(&dst_rect, config_options.option_display_border,
                             config_options.option_display_border,
                             display_adj_width, display_adj_height);

    if (config_options.display_smooth_stretch)
        vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);
    else
        vc_dispmanx_rect_set(&src_rect, 0, 0, display_adj_width << 16, display_adj_height << 16);

    dispman_display = vc_dispmanx_display_open(0);
    dispman_update = vc_dispmanx_update_start(0);
    dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display,
                                              10, &dst_rect, 0, &src_rect,
                                              DISPMANX_PROTECTION_NONE, NULL, NULL, DISPMANX_NO_ROTATE);

    //Black background surface dimensions
    vc_dispmanx_rect_set(&dst_rect, 0, 0, display_width, display_height);
    vc_dispmanx_rect_set(&src_rect, 0, 0, 128 << 16, 128 << 16);

    //Create a blank background for the whole screen, make sure width is divisible by 32!
    uint32_t crap;
    resource_bg = vc_dispmanx_resource_create(VC_IMAGE_RGB565, 128, 128, &crap);
    dispman_element_bg = vc_dispmanx_element_add(dispman_update, dispman_display,
                                                 9, &dst_rect, resource_bg, &src_rect,
                                                 DISPMANX_PROTECTION_NONE, 0, 0,
                                                 (DISPMANX_TRANSFORM_T) 0);

    nativewindow.element = dispman_element;
    if (config_options.display_smooth_stretch) {
        nativewindow.width = width;
        nativewindow.height = height;
    }
    else {
        nativewindow.width = display_adj_width;
        nativewindow.height = display_adj_height;
    }

    vc_dispmanx_update_submit_sync(dispman_update);

    surface = eglCreateWindowSurface(display, config, &nativewindow, NULL);
    assert(surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(display, surface, surface, context);
    assert(EGL_FALSE != result);

    //Smooth stretch the display size for GLES2 is the size of the bitmap
    //otherwise let GLES2 upscale (NEAR) to the size of the display
    if (config_options.display_smooth_stretch)
        gles2_create(width, height, width, height, 16);
    else
        gles2_create(display_adj_width, display_adj_height, width, height, 16);
}