Beispiel #1
0
int
RPI_CreateWindow(_THIS, SDL_Window * window)
{
    SDL_WindowData *wdata;
    SDL_VideoDisplay *display;
    SDL_DisplayData *displaydata;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    VC_DISPMANX_ALPHA_T         dispman_alpha;
    DISPMANX_UPDATE_HANDLE_T dispman_update;

    /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
    dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; 
    dispman_alpha.opacity = 0xFF; 
    dispman_alpha.mask = 0;

    /* Allocate window internal data */
    wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
    if (wdata == NULL) {
        return SDL_OutOfMemory();
    }
    display = SDL_GetDisplayForWindow(window);
    displaydata = (SDL_DisplayData *) display->driverdata;

    /* Windows have one size for now */
    window->w = display->desktop_mode.w;
    window->h = display->desktop_mode.h;

    /* OpenGL ES is the law here, buddy */
    window->flags |= SDL_WINDOW_OPENGL;

    /* Create a dispman element and associate a window to it */
    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = window->w;
    dst_rect.height = window->h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = window->w << 16;
    src_rect.height = window->h << 16;

    dispman_update = vc_dispmanx_update_start( 0 );
    wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);
    wdata->dispman_window.width = window->w;
    wdata->dispman_window.height = window->h;
    vc_dispmanx_update_submit_sync( dispman_update );
    
    if (!_this->egl_data) {
        if (SDL_GL_LoadLibrary(NULL) < 0) {
            return -1;
        }
    }
    wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);

    if (wdata->egl_surface == EGL_NO_SURFACE) {
        return SDL_SetError("Could not create GLES window surface");
    }

    /* Setup driver data for this window */
    window->driverdata = wdata;
    
    /* One window, it always has focus */
    SDL_SetMouseFocus(window);
    SDL_SetKeyboardFocus(window);

    /* Window has been successfully created */
    return 0;
}
Beispiel #2
0
	void GlContext::create(uint32_t _width, uint32_t _height)
	{
#	if BX_PLATFORM_RPI
		bcm_host_init();
#	endif // BX_PLATFORM_RPI

		m_eglLibrary = eglOpen();

		if (NULL == g_platformData.context)
		{
#	if BX_PLATFORM_RPI
			g_platformData.ndt = EGL_DEFAULT_DISPLAY;
#	endif // BX_PLATFORM_RPI

			BX_UNUSED(_width, _height);
			EGLNativeDisplayType ndt = (EGLNativeDisplayType)g_platformData.ndt;
			EGLNativeWindowType  nwh = (EGLNativeWindowType )g_platformData.nwh;

#	if BX_PLATFORM_WINDOWS
			if (NULL == g_platformData.ndt)
			{
				ndt = GetDC( (HWND)g_platformData.nwh);
			}
#	endif // BX_PLATFORM_WINDOWS

			m_display = eglGetDisplay(ndt);
			BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);

			EGLint major = 0;
			EGLint minor = 0;
			EGLBoolean success = eglInitialize(m_display, &major, &minor);
			BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor);

			BX_TRACE("EGL info:");
			const char* clientApis = eglQueryString(m_display, EGL_CLIENT_APIS);
			BX_TRACE("   APIs: %s", clientApis); BX_UNUSED(clientApis);

			const char* vendor = eglQueryString(m_display, EGL_VENDOR);
			BX_TRACE(" Vendor: %s", vendor); BX_UNUSED(vendor);

			const char* version = eglQueryString(m_display, EGL_VERSION);
			BX_TRACE("Version: %s", version); BX_UNUSED(version);

			const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS);
			BX_TRACE("Supported EGL extensions:");
			dumpExtensions(extensions);

			EGLint attrs[] =
			{
				EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,

#	if BX_PLATFORM_ANDROID
				EGL_DEPTH_SIZE, 16,
#	else
				EGL_DEPTH_SIZE, 24,
#	endif // BX_PLATFORM_
				EGL_STENCIL_SIZE, 8,

				EGL_NONE
			};

			EGLint numConfig = 0;
			success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig);
			BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");

#	if BX_PLATFORM_ANDROID

			EGLint format;
			eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
			ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format);

#	elif BX_PLATFORM_RPI
			DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
			DISPMANX_UPDATE_HANDLE_T  dispmanUpdate  = vc_dispmanx_update_start(0);

			VC_RECT_T dstRect = { 0, 0, int32_t(_width),        int32_t(_height)       };
			VC_RECT_T srcRect = { 0, 0, int32_t(_width)  << 16, int32_t(_height) << 16 };

			DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate
				, dispmanDisplay
				, 0
				, &dstRect
				, 0
				, &srcRect
				, DISPMANX_PROTECTION_NONE
				, NULL
				, NULL
				, DISPMANX_NO_ROTATE
				);

			s_dispmanWindow.element = dispmanElement;
			s_dispmanWindow.width   = _width;
			s_dispmanWindow.height  = _height;
			nwh = &s_dispmanWindow;

			vc_dispmanx_update_submit_sync(dispmanUpdate);
#	endif // BX_PLATFORM_ANDROID

			m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
			BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");

			const bool hasEglKhrCreateContext = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context");
			const bool hasEglKhrNoError       = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error");

			const uint32_t gles = BGFX_CONFIG_RENDERER_OPENGLES;

			for (uint32_t ii = 0; ii < 2; ++ii)
			{
				bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) );

				EGLint flags = 0;

#	if BX_PLATFORM_RPI
				BX_UNUSED(hasEglKhrCreateContext, hasEglKhrNoError);
#	else
				if (hasEglKhrCreateContext)
				{
					bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) );
					bx::write(&writer, EGLint(gles / 10) );

					bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) );
					bx::write(&writer, EGLint(gles % 10) );

					flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0
						| EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
						: 0
						;

					if (0 == ii)
					{
						flags |= BGFX_CONFIG_DEBUG ? 0
							| EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
//							| EGL_OPENGL_ES3_BIT_KHR
							: 0
							;

						bx::write(&writer, EGLint(EGL_CONTEXT_FLAGS_KHR) );
						bx::write(&writer, flags);
					}
				}
				else
#	endif // BX_PLATFORM_RPI
				{
					bx::write(&writer, EGLint(EGL_CONTEXT_CLIENT_VERSION) );
					bx::write(&writer, 2);
				}

				bx::write(&writer, EGLint(EGL_NONE) );

				m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs);
				if (NULL != m_context)
				{
					break;
				}

				BX_TRACE("Failed to create EGL context with EGL_CONTEXT_FLAGS_KHR (%08x).", flags);
			}

			BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");

			success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
			BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context.");
			m_current = NULL;

			eglSwapInterval(m_display, 0);
		}

		import();

		g_internalData.context = m_context;
	}
Beispiel #3
0
/* Show the specified cursor, or hide if cursor is NULL */
static int
RPI_ShowCursor(SDL_Cursor * cursor)
{
    int ret;
    DISPMANX_UPDATE_HANDLE_T update;
    RPI_CursorData *curdata;
    VC_RECT_T src_rect, dst_rect;
    SDL_Mouse *mouse;
    SDL_VideoDisplay *display;
    SDL_DisplayData *data;
    VC_DISPMANX_ALPHA_T alpha = {  DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */ , 255 /*opacity 0->255*/,  0 /* mask */ };
    
    mouse = SDL_GetMouse();
    if (mouse == NULL) {
        return -1;
    }
    
    if (cursor == NULL) {
        /* FIXME: We hide the current mouse's cursor, what we actually need is *_HideCursor */

        if ( mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
            curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
            if (curdata->element > DISPMANX_NO_HANDLE) {
                update = vc_dispmanx_update_start( 10 );
                SDL_assert( update );
                ret = vc_dispmanx_element_remove( update, curdata->element );
                SDL_assert( ret == DISPMANX_SUCCESS );
                ret = vc_dispmanx_update_submit_sync( update );
                SDL_assert( ret == DISPMANX_SUCCESS );
                curdata->element = DISPMANX_NO_HANDLE;
            }
        }
        return 0;
    }
    
    curdata = (RPI_CursorData *) cursor->driverdata;
    if (curdata == NULL) {
        return -1;
    }
    
    if (mouse->focus == NULL) {
        return -1;
    }
    
    display = SDL_GetDisplayForWindow(mouse->focus);
    if (display == NULL) {
        return -1;
    }
    
    data = (SDL_DisplayData*) display->driverdata;
    if (data == NULL) {
        return -1;
    }
    
    if (curdata->element == DISPMANX_NO_HANDLE) {
        vc_dispmanx_rect_set( &src_rect, 0, 0, curdata->w << 16, curdata->h << 16 );
        vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h);
        
        update = vc_dispmanx_update_start( 10 );
        SDL_assert( update );

        curdata->element = vc_dispmanx_element_add( update,
                                                    data->dispman_display,
                                                    SDL_RPI_MOUSELAYER, // layer
                                                    &dst_rect,
                                                    curdata->resource,
                                                    &src_rect,
                                                    DISPMANX_PROTECTION_NONE,
                                                    &alpha,
                                                    DISPMANX_NO_HANDLE, // clamp
                                                    VC_IMAGE_ROT0 );
        SDL_assert( curdata->element > DISPMANX_NO_HANDLE);
        ret = vc_dispmanx_update_submit_sync( update );
        SDL_assert( ret == DISPMANX_SUCCESS );
    }
    
    return 0;
}
Beispiel #4
0
static void *rpi_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   int32_t success;
   EGLBoolean result;
   EGLint num_config;
   rpi_t *rpi = (rpi_t*)calloc(1, sizeof(rpi_t));
   *input = NULL;

   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

   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
   };

   EGLConfig config;

   bcm_host_init();

   // get an EGL display connection
   rpi->mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
   rarch_assert(rpi->mDisplay != EGL_NO_DISPLAY);

   // initialize the EGL display connection
   result = eglInitialize(rpi->mDisplay, NULL, NULL);
   rarch_assert(result != EGL_FALSE);
   eglBindAPI(EGL_OPENVG_API);

   // get an appropriate EGL frame buffer configuration
   result = eglChooseConfig(rpi->mDisplay, attribute_list, &config, 1, &num_config);
   rarch_assert(result != EGL_FALSE);

   // create an EGL rendering context
   rpi->mContext = eglCreateContext(rpi->mDisplay, config, EGL_NO_CONTEXT, NULL);
   rarch_assert(rpi->mContext != EGL_NO_CONTEXT);

   // create an EGL window surface
   success = graphics_get_display_size(0 /* LCD */, &rpi->mScreenWidth, &rpi->mScreenHeight);
   rarch_assert(success >= 0);

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = rpi->mScreenWidth;
   dst_rect.height = rpi->mScreenHeight;

   src_rect.x = 0;
   src_rect.y = 0;
   src_rect.width = rpi->mScreenWidth << 16;
   src_rect.height = rpi->mScreenHeight << 16;

   dispman_display = vc_dispmanx_display_open(0 /* LCD */);
   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
   dispman_update = vc_dispmanx_update_start(0);

   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_NO_ROTATE);

   nativewindow.element = dispman_element;
   nativewindow.width = rpi->mScreenWidth;
   nativewindow.height = rpi->mScreenHeight;
   vc_dispmanx_update_submit_sync(dispman_update);

   rpi->mSurface = eglCreateWindowSurface(rpi->mDisplay, config, &nativewindow, NULL);
   rarch_assert(rpi->mSurface != EGL_NO_SURFACE);

   // connect the context to the surface
   result = eglMakeCurrent(rpi->mDisplay, rpi->mSurface, rpi->mSurface, rpi->mContext);
   rarch_assert(result != EGL_FALSE);

   rpi->mTexType = video->rgb32 ? VG_sABGR_8888 : VG_sARGB_1555;
   rpi->mKeepAspect = video->force_aspect;

   // check for SD televisions: they should always be 4:3
   if (dispman_modeinfo.width == 720 && (dispman_modeinfo.height == 480 || dispman_modeinfo.height == 576))
      rpi->mScreenAspect = 4.0f / 3.0f;
   else
      rpi->mScreenAspect = (float)dispman_modeinfo.width / dispman_modeinfo.height;

   VGfloat clearColor[4] = {0, 0, 0, 1};
   vgSetfv(VG_CLEAR_COLOR, 4, clearColor);

   rpi->mTextureWidth = rpi->mTextureHeight = video->input_scale * RARCH_SCALE_BASE;
   // We can't use the native format because there's no sXRGB_1555 type and
   // emulation cores can send 0 in the top bit. We lose some speed on
   // conversion but I doubt it has any real affect, since we are only drawing
   // one image at the end of the day. Still keep the alpha channel for ABGR.
   rpi->mImage = vgCreateImage(video->rgb32 ? VG_sABGR_8888 : VG_sXBGR_8888,
         rpi->mTextureWidth, rpi->mTextureHeight,
         video->smooth ? VG_IMAGE_QUALITY_BETTER : VG_IMAGE_QUALITY_NONANTIALIASED);
   rpi_set_nonblock_state(rpi, !video->vsync);

   linuxraw_input_t *linuxraw_input = (linuxraw_input_t*)input_linuxraw.init();
   if (linuxraw_input)
   {
      *input = (const input_driver_t *)&input_linuxraw;
      *input_data = linuxraw_input;
   }

#ifdef HAVE_FREETYPE
   if (g_settings.video.font_enable)
   {
      rpi->mFont = vgCreateFont(0);
      rpi->mFontHeight = g_settings.video.font_size * (g_settings.video.font_scale ? (float) rpi->mScreenWidth / 1280.0f : 1.0f);

      const char *path = g_settings.video.font_path;
      if (!*path || !path_file_exists(path))
         path = font_renderer_get_default_font();

      rpi->mFontRenderer = font_renderer_new(path, rpi->mFontHeight);

      if (rpi->mFont != VG_INVALID_HANDLE && rpi->mFontRenderer)
      {
         rpi->mFontsOn = true;

         rpi->mPaintFg = vgCreatePaint();
         rpi->mPaintBg = vgCreatePaint();
         VGfloat paintFg[] = { g_settings.video.msg_color_r, g_settings.video.msg_color_g, g_settings.video.msg_color_b, 1.0f };
         VGfloat paintBg[] = { g_settings.video.msg_color_r / 2.0f, g_settings.video.msg_color_g / 2.0f, g_settings.video.msg_color_b / 2.0f, 0.5f };

         vgSetParameteri(rpi->mPaintFg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(rpi->mPaintFg, VG_PAINT_COLOR, 4, paintFg);

         vgSetParameteri(rpi->mPaintBg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
         vgSetParameterfv(rpi->mPaintBg, VG_PAINT_COLOR, 4, paintBg);
      }
   }
#endif

   struct sigaction sa;
   sa.sa_handler = rpi_kill;
   sa.sa_flags = SA_RESTART;
   sigemptyset(&sa.sa_mask);
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);

   return rpi;
}
Beispiel #5
0
void EGLWindow::makeSurface(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h)
{
	// this code does the main window creation
	EGLBoolean result;

	static EGL_DISPMANX_WINDOW_T nativeWindow;
	// our source and destination rect for the screen
	VC_RECT_T dstRect;
	VC_RECT_T srcRect;

	// config you use OpenGL ES2.0 by default
	static const EGLint context_attributes[] =
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};


	// get an EGL display connection
	m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if(m_display == EGL_NO_DISPLAY)
	{
		std::cerr<<"error getting display\n";
		exit(EXIT_FAILURE);
	}
	// initialize the EGL display connection
	int major,minor;

	result = eglInitialize(m_display, &major, &minor);
	std::cout<<"EGL init version "<<major<<"."<<minor<<"\n";
	if(result == EGL_FALSE)
	{
		std::cerr<<"error initialising display\n";
		exit(EXIT_FAILURE);
	}
	// get our config from the config class
	m_config->chooseConfig(m_display);
	EGLConfig config=m_config->getConfig();
	// bind the OpenGL API to the EGL
	result = eglBindAPI(EGL_OPENGL_ES_API);
	if(result ==EGL_FALSE)
	{
		std::cerr<<"error binding API\n";
		exit(EXIT_FAILURE);
	}
	// create an EGL rendering context
	m_context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, context_attributes);
	if(m_context ==EGL_NO_CONTEXT)
	{
		std::cerr<<"couldn't get a valid context\n";
		exit(EXIT_FAILURE);
	}
	// create an EGL window surface the way this works is we set the dimensions of the srec
	// and destination rectangles.
	// if these are the same size there is no scaling, else the window will auto scale

	dstRect.x = _x;
	dstRect.y = _y;
	if(m_upscale == false)
	{
		dstRect.width = _w;
		dstRect.height = _h;
	}
	else
	{
		dstRect.width = m_maxWidth;
		dstRect.height = m_maxHeight;
	}
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.width = _w << 16;
	srcRect.height = _h << 16;
	// whilst this is mostly taken from demos I will try to explain what it does
	// there are very few documents on this ;-0
	// open our display with 0 being the first display, there are also some other versions
	// of this function where we can pass in a mode however the mode is not documented as
	// far as I can see
  m_dispmanDisplay = vc_dispmanx_display_open(0);
  // now we signal to the video core we are going to start updating the config
	m_dispmanUpdate = vc_dispmanx_update_start(0);
	// this is the main setup function where we add an element to the display, this is filled in
	// to the src / dst rectangles
	m_dispmanElement = vc_dispmanx_element_add ( m_dispmanUpdate, m_dispmanDisplay,
		0, &dstRect, 0,&srcRect, DISPMANX_PROTECTION_NONE, 0 ,0,DISPMANX_NO_ROTATE);
	// now we have created this element we pass it to the native window structure ready
	// no create our new EGL surface
	nativeWindow.element = m_dispmanElement;
	nativeWindow.width =_w;
	nativeWindow.height =_h;
	// we now tell the vc we have finished our update
	vc_dispmanx_update_submit_sync( m_dispmanUpdate );

	// finally we can create a new surface using this config and window
	m_surface = eglCreateWindowSurface( m_display, config, &nativeWindow, NULL );
	assert(m_surface != EGL_NO_SURFACE);
	// connect the context to the surface
	result = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
	assert(EGL_FALSE != result);
	m_activeSurface=true;

}
Beispiel #6
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);
}
Beispiel #7
0
static void ogl_init(struct state *state)
{
    int32_t success;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    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
    };

    EGLConfig config;

    // We need call eglMakeCurrent beforehand to workaround a bug on rPi.
    // https://github.com/raspberrypi/firmware/issues/99
    eglMakeCurrent(0, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display != EGL_NO_DISPLAY);

    result = eglInitialize(state->display, NULL, NULL);
    assert(result != EGL_FALSE);

    /* Get an appropriate EGL frame buffer config. */
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(result != EGL_FALSE);

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

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context != EGL_NO_CONTEXT);

    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert(success >= 0);

    /* Prepare VideoCore specific nativewindow to create a window surface. */
    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

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

    dispman_display = vc_dispmanx_display_open(0 /* LCD */);
    dispman_update = vc_dispmanx_update_start(0);

    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 */);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;

    vc_dispmanx_update_submit_sync(dispman_update);

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

    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(result != EGL_FALSE);
    assert(glGetError() == 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 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. */
}
Beispiel #10
0
static void *gfx_ctx_vc_init(void *video_driver)
{
   VC_DISPMANX_ALPHA_T alpha;
   EGLint n, major, minor;
   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

#ifdef HAVE_EGL
   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
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
#endif
   settings_t *settings = config_get_ptr();
   vc_ctx_data_t *vc    = NULL;

   if (g_egl_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return NULL;
   }

   vc = (vc_ctx_data_t*)calloc(1, sizeof(*vc));

   if (!vc)
       return NULL;

   bcm_host_init();

#ifdef HAVE_EGL
   if (!egl_init_context(&vc->egl, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribute_list))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API) ? context_attributes : NULL))
   {
      egl_report_error();
      goto error;
   }
#endif

   /* Create an EGL window surface. */
   if (graphics_get_display_size(0 /* LCD */, &vc->fb_width, &vc->fb_height) < 0)
      goto error;

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = vc->fb_width;
   dst_rect.height = vc->fb_height;

   src_rect.x = 0;
   src_rect.y = 0;

   /* Use dispmanx upscaling if fullscreen_x 
    * and fullscreen_y are set. */
   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;
      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         src_rect.width = (unsigned)(settings->video.fullscreen_y * dstAspect) << 16;
      else
         src_rect.width = settings->video.fullscreen_x << 16;
      src_rect.height = settings->video.fullscreen_y << 16;
   }
   else
   {
      src_rect.width  = vc->fb_width << 16;
      src_rect.height = vc->fb_height << 16;
   }

   dispman_display = vc_dispmanx_display_open(0 /* LCD */);
   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
   dispman_update = vc_dispmanx_update_start(0);

   alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity = 255;
   alpha.mask = 0;

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

   nativewindow.element = dispman_element;

   /* Use dispmanx upscaling if fullscreen_x and fullscreen_y are set. */

   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which 
       * can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;

      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         nativewindow.width = (unsigned)(settings->video.fullscreen_y * dstAspect);
      else
         nativewindow.width = settings->video.fullscreen_x;
      nativewindow.height = settings->video.fullscreen_y;
   }
   else
   {
      nativewindow.width = vc->fb_width;
      nativewindow.height = vc->fb_height;
   }
   vc_dispmanx_update_submit_sync(dispman_update);

#ifdef HAVE_EGL
   if (!egl_create_surface(&vc->egl, &nativewindow))
      goto error;
#endif

   return vc;

error:
   gfx_ctx_vc_destroy(video_driver);
   return NULL;
}
Beispiel #11
0
static bool pi_create_display(ALLEGRO_DISPLAY *display)
{
    ALLEGRO_DISPLAY_RASPBERRYPI *d = (void *)display;
    ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = _al_get_new_display_settings();

    egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (egl_display == EGL_NO_DISPLAY) {
        return false;
    }

    int major, minor;
    if (!eglInitialize(egl_display, &major, &minor)) {
        return false;
    }

    static EGLint attrib_list[] =
    {
        EGL_DEPTH_SIZE, 0,
        EGL_STENCIL_SIZE, 0,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    attrib_list[1] = eds->settings[ALLEGRO_DEPTH_SIZE];
    attrib_list[3] = eds->settings[ALLEGRO_STENCIL_SIZE];

    if (eds->settings[ALLEGRO_RED_SIZE] || eds->settings[ALLEGRO_GREEN_SIZE] ||
            eds->settings[ALLEGRO_BLUE_SIZE] ||
            eds->settings[ALLEGRO_ALPHA_SIZE]) {
        attrib_list[5] = eds->settings[ALLEGRO_RED_SIZE];
        attrib_list[7] = eds->settings[ALLEGRO_GREEN_SIZE];
        attrib_list[9] = eds->settings[ALLEGRO_BLUE_SIZE];
        attrib_list[11] = eds->settings[ALLEGRO_ALPHA_SIZE];
    }
    else if (eds->settings[ALLEGRO_COLOR_SIZE] == 16) {
        attrib_list[5] = 5;
        attrib_list[7] = 6;
        attrib_list[9] = 5;
        attrib_list[11] = 0;
    }

    EGLConfig config;
    int num_configs;

    if (!eglChooseConfig(egl_display, attrib_list, &config, 1, &num_configs)) {
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);

    int es_ver = (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) ?
                 2 : 1;

    static EGLint ctxattr[3] = {
        EGL_CONTEXT_CLIENT_VERSION, 0xDEADBEEF,
        EGL_NONE
    };

    ctxattr[1] = es_ver;

    egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctxattr);
    if (egl_context == EGL_NO_CONTEXT) {
        return false;
    }

    static EGL_DISPMANX_WINDOW_T nativewindow;
    DISPMANX_ELEMENT_HANDLE_T dispman_element;

    int dx, dy, screen_width, screen_height;
    _al_raspberrypi_get_screen_info(&dx, &dy, &screen_width, &screen_height);

    d->cursor_offset_x = dx;
    d->cursor_offset_y = dy;

    dst_rect.x = dx;
    dst_rect.y = dy;
    dst_rect.width = screen_width;
    dst_rect.height = screen_height;

    d->screen_width = screen_width;
    d->screen_height = screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = display->w << 16;
    src_rect.height = display->h << 16;

    dispman_display = vc_dispmanx_display_open(0 /* LCD */);
    dispman_update = vc_dispmanx_update_start(0);

    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_NO_ROTATE/*transform*/
                      );

    nativewindow.element = dispman_element;
    nativewindow.width = display->w;
    nativewindow.height = display->h;
    vc_dispmanx_update_submit_sync(dispman_update);

    egl_window = eglCreateWindowSurface(
                     egl_display, config, &nativewindow, NULL);
    if (egl_window == EGL_NO_SURFACE) {
        return false;
    }

    if (!eglMakeCurrent(egl_display, egl_window, egl_window, egl_context)) {
        return false;
    }

    return true;
}
static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win)
{
   int wid = (int)win;
   if(wid>-NUM_WIN && wid <=0) {
      /*
       * Special identifiers indicating the default windows. Either use the
       * one we've got or create a new one
       * simple hack for VMCSX_VC4_1.0 release to demonstrate concurrent running of apps under linux

       * win ==  0 => full screen window on display 0
       * win == -1 => 1/4 screen top left window on display 0
       * win == -2 => 1/4 screen top right window on display 0
       * win == -3 => 1/4 screen bottom left window on display 0
       * win == -4 => 1/4 screen bottom right window on display 0
       * win == -5 => full screen window on display 2

       * it is expected that Open WFC will provide a proper mechanism in the near future
       */
      wid = -wid;

      if (!have_default_dwin[wid]) {
         DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open( (wid == 5) ? 2 : 0 );
         DISPMANX_MODEINFO_T info;
         vc_dispmanx_display_get_info(display, &info);
         int32_t dw = info.width, dh = info.height;

         DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start( 0 );
         VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
         VC_RECT_T dst_rect;
         VC_RECT_T src_rect;

         int x, y, width, height, layer;

         switch(wid)
         {
         case 0:
            x = 0;    y = 0;    width = dw;   height = dh;   layer = 0; break;
         case 1:
            x = 0;    y = 0;    width = dw/2; height = dh/2; layer = 0; break;
         case 2:
            x = dw/2; y = 0;    width = dw/2; height = dh/2; layer = 0; break;
         case 3:
            x = 0;    y = dh/2; width = dw/2; height = dh/2; layer = 0; break;
         case 4:
            x = dw/2; y = dh/2; width = dw/2; height = dh/2; layer = 0; break;
         case 5:
            x = 0;    y = 0;    width = dw;   height = dh;   layer = 0; break;
         }

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

         dst_rect.x = x;
         dst_rect.y = y;
         dst_rect.width = width;
         dst_rect.height = height;

         default_dwin[wid].element = vc_dispmanx_element_add ( update, display,
            layer, &dst_rect, 0/*src*/,
            &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, 0/*transform*/);

         default_dwin[wid].width = width;
         default_dwin[wid].height = height;

         vc_dispmanx_update_submit_sync( update );

         have_default_dwin[wid] = true;
      }
      return &default_dwin[wid];
   } else
      return (EGL_DISPMANX_WINDOW_T*)win;
}
Beispiel #13
0
static bool gfx_ctx_vc_init(void *data)
{
   EGLint num_config;
   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

   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
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
   settings_t *settings = config_get_ptr();

   RARCH_LOG("[VC/EGL]: Initializing...\n");
   if (g_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return false;
   }

   bcm_host_init();

   /* Get an EGL display connection. */
   g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
   if (!g_egl_dpy)
      goto error;

   /* Initialize the EGL display connection. */
   if (!eglInitialize(g_egl_dpy, NULL, NULL))
      goto error;

   /* Get an appropriate EGL frame buffer configuration. */
   if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_egl_config, 1, &num_config))
      goto error;

   /* Create an EGL rendering context. */
   g_egl_ctx = eglCreateContext(
         g_egl_dpy, g_egl_config, EGL_NO_CONTEXT,
         (g_api == GFX_CTX_OPENGL_ES_API) ? context_attributes : NULL);
   if (!g_egl_ctx)
      goto error;

   if (g_use_hw_ctx)
   {
      g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_egl_config, g_egl_ctx,
            context_attributes);
      RARCH_LOG("[VC/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);

      if (g_egl_hw_ctx == EGL_NO_CONTEXT)
         goto error;
   }

   /* Create an EGL window surface. */
   if (graphics_get_display_size(0 /* LCD */, &g_fb_width, &g_fb_height) < 0)
      goto error;

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = g_fb_width;
   dst_rect.height = g_fb_height;

   src_rect.x = 0;
   src_rect.y = 0;

   /* Use dispmanx upscaling if fullscreen_x 
    * and fullscreen_y are set. */
   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)g_fb_width / (float)g_fb_height;
      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         src_rect.width = (unsigned)(settings->video.fullscreen_y * dstAspect) << 16;
      else
         src_rect.width = settings->video.fullscreen_x << 16;
      src_rect.height = settings->video.fullscreen_y << 16;
   }
   else
   {
      src_rect.width = g_fb_width << 16;
      src_rect.height = g_fb_height << 16;
   }

   dispman_display = vc_dispmanx_display_open(0 /* LCD */);
   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
   dispman_update = vc_dispmanx_update_start(0);

   VC_DISPMANX_ALPHA_T alpha;
   alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity = 255;
   alpha.mask = 0;

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

   nativewindow.element = dispman_element;

   /* Use dispmanx upscaling if fullscreen_x and fullscreen_y are set. */

   if (settings->video.fullscreen_x != 0 &&
      settings->video.fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which 
       * can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->video.fullscreen_x / (float)settings->video.fullscreen_y;
      float dstAspect = (float)g_fb_width / (float)g_fb_height;

      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         nativewindow.width = (unsigned)(settings->video.fullscreen_y * dstAspect);
      else
         nativewindow.width = settings->video.fullscreen_x;
      nativewindow.height = settings->video.fullscreen_y;
   }
   else
   {
      nativewindow.width = g_fb_width;
      nativewindow.height = g_fb_height;
   }
   vc_dispmanx_update_submit_sync(dispman_update);

   g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_egl_config, &nativewindow, NULL);
   if (!g_egl_surf)
      goto error;

   /* Connect the context to the surface. */
   if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
      goto error;

   return true;

error:
   gfx_ctx_vc_destroy(data);
   return false;
}
Beispiel #14
0
// Description: Sets the display, OpenGL|ES context and screen stuff
void init_ogl(gl_t *state, void *launcher_state)
{
    bcm_host_init();

    // Initialize struct
    memset(state, 0, sizeof(gl_t));
    state->controller_1_fd = -1;
    state->controller_2_fd = -1;
    state->window_should_close = false;

    // Set a user pointer up
    state->user_pointer = launcher_state;

    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    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
    };
   
    static const EGLint context_attributes[] =
    {
       EGL_CONTEXT_CLIENT_VERSION, 2,
       EGL_NONE
    }; 

    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);
 
    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

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

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

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;
      
    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );

    VC_DISPMANX_ALPHA_T alpha;
    alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
    alpha.opacity = 255;
    alpha.mask = 0;         

    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
      0/*layer*/, &dst_rect, 0/*src*/,
      &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, 0/*transform*/);
      
    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );
      
    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

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

    // Open input event
    state->controller_1_fd = open("/dev/input/event1",O_RDONLY|O_NONBLOCK);
    state->controller_2_fd = open("/dev/input/event2",O_RDONLY|O_NONBLOCK);
}
Beispiel #15
0
void init_ogl(CUBE_STATE_T *state)
{
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

//    bcm_host_init();

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    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
	};

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

    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);

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

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


    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    state->screen_width = 1024;

    state->screen_height = 1024;

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

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

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );

    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*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

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

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);
}
Beispiel #16
0
/** @brief Obtain a reference to the system's native window
 * @param width : desired pixel width of the window (not used by all platforms)
 * @param height : desired pixel height of the window (not used by all platforms)
 * @return : 0 if the function passed, else 1
 */
int8_t GetNativeWindow( uint16_t width, uint16_t height )
{
    nativeWindow = 0;

#if defined(WIZ) || defined(CAANOO)

    nativeWindow = (NativeWindowType)malloc(16*1024);

    if(nativeWindow == NULL) {
        printf( "EGLport ERROR: Memory for window Failed\n" );
        return 1;
    }

#elif defined(RPI)

    EGLBoolean result;
    uint32_t screen_width, screen_height;
    static EGL_DISPMANX_WINDOW_T nativewindow;
    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    /* create an EGL window surface */
    result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
    if(result < 0) {
        printf( "EGLport ERROR: RPi graphicget_display_size failed\n" );
        return 1;
    }

    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 = width << 16;
    src_rect.height = height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update  = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
      0 /*layer*/, &dst_rect, 0 /*src*/,
      &src_rect, DISPMANX_PROTECTION_NONE,  (VC_DISPMANX_ALPHA_T*)0 /*alpha*/,  (DISPMANX_CLAMP_T*)0 /*clamp*/,  (DISPMANX_TRANSFORM_T)0 /*transform*/);

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

    nativeWindow = (NativeWindowType)&nativewindow;

#else /* default */

    if (eglSettings[CFG_MODE] == RENDER_RAW)        /* RAW FB mode */
    {
        nativeWindow = 0;
    }
    else if(eglSettings[CFG_MODE] == RENDER_SDL)    /* SDL/X11 mode */
    {
#if defined(USE_EGL_SDL)
        /* SDL_GetWMInfo is populated when display was opened */
        nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window;

        if (nativeWindow == 0)
        {
            printf( "EGLport ERROR: unable to get window!\n" );
            return 1;
        }
#else
        printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
#endif
    }
    else
    {
        printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] );
        return 1;
    }

#endif /* WIZ / CAANOO */

    return 0;
}
Beispiel #17
0
bool GBASDLGLES2Init(struct SDLSoftwareRenderer* renderer) {
#ifdef BUILD_RASPI
	bcm_host_init();
	renderer->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	int major, minor;
	if (EGL_FALSE == eglInitialize(renderer->display, &major, &minor)) {
		printf("Failed to initialize EGL");
		return false;
	}

	if (EGL_FALSE == eglBindAPI(EGL_OPENGL_ES_API)) {
		printf("Failed to get GLES API");
		return false;
	}

	const EGLint requestConfig[] = {
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 5,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, 1,
		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_NONE
	};

	EGLConfig config;
	EGLint numConfigs;

	if (EGL_FALSE == eglChooseConfig(renderer->display, requestConfig, &config, 1, &numConfigs)) {
		printf("Failed to choose EGL config\n");
		return false;
	}

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

	int dispWidth = 240, dispHeight = 160, adjWidth;
	renderer->context = eglCreateContext(renderer->display, config, EGL_NO_CONTEXT, contextAttributes);
	graphics_get_display_size(0, &dispWidth, &dispHeight);
	adjWidth = dispHeight / 2 * 3;

	DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
	DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);

	VC_RECT_T destRect = {
		.x = (dispWidth - adjWidth) / 2,
		.y = 0,
		.width = adjWidth,
		.height = dispHeight
	};

	VC_RECT_T srcRect = {
		.x = 0,
		.y = 0,
		.width = 240 << 16,
		.height = 160 << 16
	};

	DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, 0);
	vc_dispmanx_update_submit_sync(update);

	renderer->window.element = element;
	renderer->window.width = dispWidth;
	renderer->window.height = dispHeight;

	renderer->surface = eglCreateWindowSurface(renderer->display, config, &renderer->window, 0);
	if (EGL_FALSE == eglMakeCurrent(renderer->display, renderer->surface, renderer->surface, renderer->context)) {
		return false;
	}
#else
	GBASDLGLCommonInit(renderer);
#endif

	renderer->d.outputBuffer = memalign(16, 256 * 256 * 4);
	renderer->d.outputBufferStride = 256;

	GBAGLES2ContextCreate(&renderer->gl2);
	renderer->gl2.d.user = renderer;
	renderer->gl2.d.lockAspectRatio = renderer->lockAspectRatio;
	renderer->gl2.d.filter = renderer->filter;
	renderer->gl2.d.swap = GBASDLGLCommonSwap;
	renderer->gl2.d.init(&renderer->gl2.d, 0);
	return true;
}

void GBASDLGLES2Runloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
	SDL_Event event;
	struct VideoBackend* v = &renderer->gl2.d;

	while (context->state < THREAD_EXITING) {
		while (SDL_PollEvent(&event)) {
			GBASDLHandleEvent(context, &renderer->player, &event);
		}

		if (GBASyncWaitFrameStart(&context->sync)) {
			v->postFrame(v, renderer->d.outputBuffer);
		}
		GBASyncWaitFrameEnd(&context->sync);
		v->drawFrame(v);
#ifdef BUILD_RASPI
		eglSwapBuffers(renderer->display, renderer->surface);
#else
		v->swap(v);
#endif
	}
}

void GBASDLGLES2Deinit(struct SDLSoftwareRenderer* renderer) {
	if (renderer->gl2.d.deinit) {
		renderer->gl2.d.deinit(&renderer->gl2.d);
	}
#ifdef BUILD_RASPI
	eglMakeCurrent(renderer->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
	eglDestroySurface(renderer->display, renderer->surface);
	eglDestroyContext(renderer->display, renderer->context);
	eglTerminate(renderer->display);
	bcm_host_deinit();
#elif SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_GL_DeleteContext(renderer->glCtx);
#endif
	free(renderer->d.outputBuffer);
}
	bool createSurface() //unsigned int display_width, unsigned int display_height)
	{
		LOG(LogInfo) << "Starting SDL...";

		if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) != 0)
		{
			LOG(LogError) << "Error initializing SDL!\n	" << SDL_GetError() << "\n" << "Are you in the 'video', 'audio', and 'input' groups? Is X closed? Is your firmware up to date? Are you using at least the 192/64 memory split?";
			return false;
		}

		sdlScreen = SDL_SetVideoMode(1, 1, 0, SDL_SWSURFACE);
		if(sdlScreen == NULL)
		{
			LOG(LogError) << "Error creating SDL window for input!";
			return false;
		}


		LOG(LogInfo) << "Creating surface...";

		DISPMANX_ELEMENT_HANDLE_T dispman_element;
		DISPMANX_DISPLAY_HANDLE_T dispman_display;
		DISPMANX_UPDATE_HANDLE_T dispman_update;
		VC_RECT_T dst_rect;
		VC_RECT_T src_rect;



		display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
		if(display == EGL_NO_DISPLAY)
		{
			LOG(LogError) << "Error getting display!";
			return false;
		}

		bool result = eglInitialize(display, NULL, NULL);
		if(result == EGL_FALSE)
		{
			LOG(LogError) << "Error initializing display!";
			return false;
		}

		result = eglBindAPI(EGL_OPENGL_ES_API);
		if(result == EGL_FALSE)
		{
			LOG(LogError) << "Error binding API!";
			return false;
		}


		static const EGLint config_attributes[] =
		{
			EGL_RED_SIZE, 8,
			EGL_GREEN_SIZE, 8,
			EGL_BLUE_SIZE, 8,
			EGL_ALPHA_SIZE, 8,
			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
			EGL_NONE
		};

		GLint numConfigs;
		result = eglChooseConfig(display, config_attributes, &config, 1, &numConfigs);

		if(result == EGL_FALSE)
		{
			LOG(LogError) << "Error choosing config!";
			return false;
		}


		context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
		if(context == EGL_NO_CONTEXT)
		{
			LOG(LogError) << "Error getting context!\n	" << eglGetError();
			return false;
		}




		if(!display_width || !display_height)
		{
			bool success = graphics_get_display_size(0, &display_width, &display_height); //0 = LCD

			if(success < 0)
			{
				LOG(LogError) << "Error getting display size!";
				return false;
			}
		}

		LOG(LogInfo) << "Resolution: " << display_width << "x" << display_height << "...";


		dst_rect.x = 0; dst_rect.y = 0;
		dst_rect.width = display_width; dst_rect.height = display_height;

		src_rect.x = 0; src_rect.y = 0;
		src_rect.width = display_width << 16; src_rect.height = display_height << 16;

		dispman_display = vc_dispmanx_display_open(0); //0 = LCD
		dispman_update = vc_dispmanx_update_start(0);

		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_NO_ROTATE /*transform*/);

		nativewindow.element = dispman_element;
		nativewindow.width = display_width; nativewindow.height = display_height;
		vc_dispmanx_update_submit_sync(dispman_update);




		surface = eglCreateWindowSurface(display, config, &nativewindow, NULL);
		if(surface == EGL_NO_SURFACE)
		{
			LOG(LogError) << "Error creating window surface!";
			return false;
		}

		result = eglMakeCurrent(display, surface, surface, context);
		if(result == EGL_FALSE)
		{
			LOG(LogError) << "Error with eglMakeCurrent!";
			return false;
		}


		LOG(LogInfo) << "Created surface successfully!";

		return true;
	}
ViewBackend::Cursor::~Cursor()
{
    DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0);
    vc_dispmanx_element_remove(updateHandle, cursorHandle);
    vc_dispmanx_update_submit_sync(updateHandle);
}
Beispiel #20
0
/***********************************************************
 * Name: init_ogl
 *
 * Arguments:
 *       CUBE_STATE_T *state - holds OGLES model info
 *
 * Description: Sets the display, OpenGL|ES context and screen stuff
 *
 * Returns: void
 *
 ***********************************************************/
static void init_ogl(CUBE_STATE_T *state)
{
   int32_t success = 0;
   EGLBoolean result;
   EGLint num_config;

   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

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

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

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

   // get an appropriate EGL frame buffer configuration
   // this uses a BRCM extension that gets the closest match, rather than standard which returns anything that matches
   result = eglSaneChooseConfigBRCM(state->display, attribute_list, &config, 1, &num_config);
   assert(EGL_FALSE != result);

   // create an EGL rendering context
   state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
   assert(state->context!=EGL_NO_CONTEXT);

   // create an EGL window surface
   success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
   assert( success >= 0 );

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = state->screen_width;
   dst_rect.height = state->screen_height;
      
   src_rect.x = 0;
   src_rect.y = 0;
   src_rect.width = state->screen_width << 16;
   src_rect.height = state->screen_height << 16;        

   dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
   dispman_update = vc_dispmanx_update_start( 0 );
         
   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*/, 0/*transform*/);
      
   nativewindow.element = dispman_element;
   nativewindow.width = state->screen_width;
   nativewindow.height = state->screen_height;
   vc_dispmanx_update_submit_sync( dispman_update );
      
   state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
   assert(state->surface != EGL_NO_SURFACE);

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

   // Set background color and clear buffers
   glClearColor(0.15f, 0.25f, 0.35f, 1.0f);

   // Enable back face culling.
   glEnable(GL_CULL_FACE);

   glMatrixMode(GL_MODELVIEW);
}
Beispiel #21
0
static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
{
   VC_DISPMANX_ALPHA_T alpha;
   EGLint n, major, minor;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   DISPMANX_MODEINFO_T dispman_modeinfo;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

#ifdef HAVE_EGL
   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_DEPTH_SIZE, 16,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };

   static const EGLint context_attributes[] =
   {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
   };
#endif
   settings_t *settings = config_get_ptr();
   vc_ctx_data_t *vc    = NULL;

   if (g_egl_inited)
   {
      RARCH_ERR("[VC/EGL]: Attempted to re-initialize driver.\n");
      return NULL;
   }

   vc = (vc_ctx_data_t*)calloc(1, sizeof(*vc));

   if (!vc)
       return NULL;

   /* If we set this env variable, Broadcom's EGL implementation will block
    * on vsync with a double buffer when we call eglSwapBuffers. Less input lag!
    * Has to be done before any EGL call.
    * NOTE this is commented out because it should be the right way to do it, but
    * currently it doesn't work, so we are using an vsync callback based solution.*/
   /* if (video_info->max_swapchain_images <= 2)
      setenv("V3D_DOUBLE_BUFFER", "1", 1);
   else
      setenv("V3D_DOUBLE_BUFFER", "0", 1); */

   bcm_host_init();

#ifdef HAVE_EGL
   if (!egl_init_context(&vc->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
            &major, &minor, &n, attribute_list))
   {
      egl_report_error();
      goto error;
   }

   if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API)
            ? context_attributes : NULL))
   {
      egl_report_error();
      goto error;
   }
#endif

   /* Create an EGL window surface. */
   if (graphics_get_display_size(0 /* LCD */, &vc->fb_width, &vc->fb_height) < 0)
      goto error;

   dst_rect.x      = 0;
   dst_rect.y      = 0;
   dst_rect.width  = vc->fb_width;
   dst_rect.height = vc->fb_height;

   src_rect.x      = 0;
   src_rect.y      = 0;

   /* Use dispmanx upscaling if fullscreen_x
    * and fullscreen_y are set. */
   if ((settings->uints.video_fullscreen_x != 0) &&
       (settings->uints.video_fullscreen_y != 0))
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect        = (float)settings->uints.video_fullscreen_x / (float)settings->uints.video_fullscreen_y;
      float dstAspect        = (float)vc->fb_width / (float)vc->fb_height;
      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         src_rect.width      = (unsigned)(settings->uints.video_fullscreen_y * dstAspect) << 16;
      else
         src_rect.width      = settings->uints.video_fullscreen_x << 16;
      src_rect.height        = settings->uints.video_fullscreen_y << 16;
   }
   else
   {
      src_rect.width         = vc->fb_width << 16;
      src_rect.height        = vc->fb_height << 16;
   }

   dispman_display           = vc_dispmanx_display_open(0 /* LCD */);
   vc->dispman_display       = dispman_display;

   vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);

   dispman_update            = vc_dispmanx_update_start(0);

   alpha.flags               = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
   alpha.opacity             = 255;
   alpha.mask                = 0;

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

   vc->native_window.element = dispman_element;

   /* Use dispmanx upscaling if fullscreen_x and fullscreen_y are set. */

   if (settings->uints.video_fullscreen_x != 0 &&
       settings->uints.video_fullscreen_y != 0)
   {
      /* Keep input and output aspect ratio equal.
       * There are other aspect ratio settings which
       * can be used to stretch video output. */

      /* Calculate source and destination aspect ratios. */
      float srcAspect = (float)settings->uints.video_fullscreen_x
         / (float)settings->uints.video_fullscreen_y;
      float dstAspect = (float)vc->fb_width / (float)vc->fb_height;

      /* If source and destination aspect ratios are not equal correct source width. */
      if (srcAspect != dstAspect)
         vc->native_window.width = (unsigned)(settings->uints.video_fullscreen_y * dstAspect);
      else
         vc->native_window.width = settings->uints.video_fullscreen_x;
      vc->native_window.height   = settings->uints.video_fullscreen_y;
   }
   else
   {
      vc->native_window.width = vc->fb_width;
      vc->native_window.height = vc->fb_height;
   }
   vc_dispmanx_update_submit_sync(dispman_update);

#ifdef HAVE_EGL
   if (!egl_create_surface(&vc->egl, &vc->native_window))
      goto error;
#endif

   /* For vsync after eglSwapBuffers when max_swapchain < 3 */
   vc->vsync_condition       = scond_new();
   vc->vsync_condition_mutex = slock_new();
   vc->vsync_callback_set    = false;

   if (video_info->max_swapchain_images <= 2)
   {
      /* Start sending vsync callbacks so we can wait for vsync after eglSwapBuffers */
      vc_dispmanx_vsync_callback(vc->dispman_display,
            dispmanx_vsync_callback, (void*)vc);
      vc->vsync_callback_set = true;
   }

   return vc;

error:
   gfx_ctx_vc_destroy(video_driver);
   return NULL;
}
Beispiel #22
0
int rpi_setup_element(int x, int y, Uint32 video_flags, int update)
{
	// this code is based on the work of Ben O'Steen
	// http://benosteen.wordpress.com/2012/04/27/using-opengl-es-2-0-on-the-raspberry-pi-without-x-windows/
	// https://github.com/benosteen/opengles-book-samples/tree/master/Raspi
	DISPMANX_UPDATE_HANDLE_T dispman_update;
	VC_RECT_T dst_rect;
	VC_RECT_T src_rect;
	VC_DISPMANX_ALPHA_T alpha_descriptor;

	uint32_t rpi_display_device=DISPMANX_ID_MAIN_LCD;
	uint32_t display_width;
	uint32_t display_height;
	int success;

	success = graphics_get_display_size(rpi_display_device, &display_width, &display_height);
	if ( success < 0 ) {
		con_printf(CON_URGENT, "Could not get RPi display size, assuming 640x480\n");
		display_width=640;
		display_height=480;
	}

	if ((uint32_t)x > display_width) {
		con_printf(CON_URGENT, "RPi: Requested width %d exceeds display width %u, scaling down!\n",
			x,display_width);
		x=(int)display_width;
	}
	if ((uint32_t)y > display_height) {
		con_printf(CON_URGENT, "RPi: Requested height %d exceeds display height %u, scaling down!\n",
			y,display_height);
		y=(int)display_height;
	}

	con_printf(CON_DEBUG, "RPi: display resolution %ux%u, game resolution: %dx%d (%s)\n", display_width, display_height, x, y, (video_flags & SDL_FULLSCREEN)?"fullscreen":"windowed");
	if (video_flags & SDL_FULLSCREEN) {
		/* scale to the full display size... */
		dst_rect.x = 0;
		dst_rect.y = 0;
		dst_rect.width = display_width;
		dst_rect.height= display_height;
	} else {
		/* TODO: we could query the position of the X11 window here
		   and try to place the ovelray exactly above that...,
		   we would have to track window movements, though ... */
		dst_rect.x = 0;
		dst_rect.y = 0;
		dst_rect.width = (uint32_t)x;
		dst_rect.height= (uint32_t)y;
	}

	src_rect.x = 0;
	src_rect.y = 0;
	src_rect.width = ((uint32_t)x)<< 16;
	src_rect.height =((uint32_t)y)<< 16;

	/* we do not want our overlay to be blended against the background */
	alpha_descriptor.flags=DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
	alpha_descriptor.opacity=0xffffffff;
	alpha_descriptor.mask=0;

	// open display, if we do not already have one ...
	if (dispman_display == DISPMANX_NO_HANDLE) {
		con_printf(CON_DEBUG, "RPi: opening display: %u\n",rpi_display_device);
		dispman_display = vc_dispmanx_display_open(rpi_display_device);
		if (dispman_display == DISPMANX_NO_HANDLE) {
			con_printf(CON_URGENT,"RPi: failed to open display: %u\n",rpi_display_device);
		}
	}

	if (dispman_element != DISPMANX_NO_HANDLE) {
		if (!update) {
			// if the element already exists, and we cannot update it, so recreate it
			rpi_destroy_element();
		}
	} else {
		// if the element does not exist, we cannot do an update
		update=0;
	}

	dispman_update = vc_dispmanx_update_start( 0 );

	if (update) {
		con_printf(CON_DEBUG, "RPi: updating display manager element\n");
		vc_dispmanx_element_change_attributes ( dispman_update, nativewindow.element,
							ELEMENT_CHANGE_DEST_RECT | ELEMENT_CHANGE_SRC_RECT,
							0 /*layer*/, 0 /*opacity*/,
							&dst_rect, &src_rect,
							0 /*mask*/, VC_IMAGE_ROT0 /*transform*/);
	} else {
		// create a new element
		con_printf(CON_DEBUG, "RPi: creating display manager element\n");
		dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
								0 /*layer*/, &dst_rect, 0 /*src*/,
								&src_rect, DISPMANX_PROTECTION_NONE,
								&alpha_descriptor, NULL /*clamp*/,
								VC_IMAGE_ROT0 /*transform*/);
		if (dispman_element == DISPMANX_NO_HANDLE) {
			con_printf(CON_URGENT,"RPi: failed to creat display manager elemenr\n");
		}
		nativewindow.element = dispman_element;
	}
	nativewindow.width = display_width;
	nativewindow.height = display_height;
	vc_dispmanx_update_submit_sync( dispman_update );

	return 0;
}
Beispiel #23
0
static int rpi_init(struct MPGLContext *ctx, int flags)
{
    struct priv *p = ctx->priv;
    struct vo *vo = ctx->vo;

    p->egl.log = vo->log;

    bcm_host_init();

    p->display = vc_dispmanx_display_open(0);
    p->update = vc_dispmanx_update_start(0);
    if (!p->display || !p->update) {
        MP_FATAL(ctx->vo, "Could not get DISPMANX objects.\n");
        goto fail;
    }

    uint32_t w, h;
    if (graphics_get_display_size(0, &w, &h) < 0) {
        MP_FATAL(ctx->vo, "Could not get display size.\n");
        goto fail;
    }

    // dispmanx is like a neanderthal version of Wayland - you can add an
    // overlay any place on the screen. Just use the whole screen.
    VC_RECT_T dst = {.width = w, .height = h};
    VC_RECT_T src = {.width = w << 16, .height = h << 16};
    VC_DISPMANX_ALPHA_T alpha = {
        .flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
        .opacity = 0xFF,
    };
    p->window = vc_dispmanx_element_add(p->update, p->display, 1, &dst, 0,
                                        &src, DISPMANX_PROTECTION_NONE, &alpha, 0, 0);
    if (!p->window) {
        MP_FATAL(ctx->vo, "Could not add DISPMANX element.\n");
        goto fail;
    }

    vc_dispmanx_update_submit_sync(p->update);

    if (mp_egl_rpi_init(&p->egl, p->window, w, h) < 0)
        goto fail;

    ctx->gl = p->egl.gl;

    vo->dwidth = p->w = w;
    vo->dheight = p->h = h;

    return 0;

fail:
    rpi_uninit(ctx);
    return -1;
}

static int rpi_reconfig(struct MPGLContext *ctx)
{
    struct priv *p = ctx->priv;
    ctx->vo->dwidth = p->w;
    ctx->vo->dheight = p->h;
    return 0;
}

static void rpi_swap_buffers(MPGLContext *ctx)
{
    struct priv *p = ctx->priv;
    eglSwapBuffers(p->egl.egl_display, p->egl.egl_surface);
}

static int rpi_control(MPGLContext *ctx, int *events, int request, void *arg)
{
    return VO_NOTIMPL;
}

const struct mpgl_driver mpgl_driver_rpi = {
    .name           = "rpi",
    .priv_size      = sizeof(struct priv),
    .init           = rpi_init,
    .reconfig       = rpi_reconfig,
    .swap_buffers   = rpi_swap_buffers,
    .control        = rpi_control,
    .uninit         = rpi_uninit,
};
//==============================================================================
void initGL(int argc, char **argv){

    // Start OpenGL ES
    bcm_host_init();

    // Clear application state
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativeviewport;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    uint32_t screen_width;
    uint32_t screen_height;

    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_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();

    // create an EGL viewport surface
    success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
    assert( success >= 0 );

    //  Initially the viewport is for all the screen
    viewport.x = 0;
    viewport.y = 0;
    viewport.z = screen_width;
    viewport.w = screen_height;

    dst_rect.x = viewport.x;
    dst_rect.y = viewport.y;
    dst_rect.width = viewport.z;
    dst_rect.height = viewport.w;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = viewport.z << 16;
    src_rect.height = viewport.w << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );

    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 = viewport.z;
    nativeviewport.height = viewport.w;
    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();

    // Set background color and clear buffers
    // glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    // glClear( GL_COLOR_BUFFER_BIT );

    setWindowSize(viewport.z,viewport.w);
    mouse.x = viewport.z*0.5;
    mouse.y = viewport.w*0.5;
    check();

    initMouse();
    ///printf("OpenGL Initialize at %i,%i,%i,%i\n",viewport.x,viewport.y,viewport.z,viewport.w);
}
ogEGLWindow::ogEGLWindow( uint32_t a_width, uint32_t a_height, ogEGLConfigShPtr a_config_shptr )
{
	this->m_width = a_width;
	this->m_height = a_height;

	// get max display size
	int32_t result = 0;
	result = graphics_get_display_size( 0, &(this->m_max_width), &(this->m_max_height) ); //!!!
	std::cout << "ogEGLWindowShPtr::ogEGLWindow : graphics get display size result = " << result << ", max width : " << this->m_max_width << std::endl; 
	
	assert( result >= 0 );

	if ( this->m_max_width < a_width ) { this->m_width = this->m_max_width; }
	if ( this->m_max_height < a_height ) { this->m_height = this->m_max_height; }

	this->m_config_shptr = a_config_shptr;

	std::cout << "ogEGLWindow::ogEGLWindow | Display max width : " << this->m_max_width << ", max height : " << this->m_max_height << std::endl;

	// make surface
	EGLBoolean success;

	static EGL_DISPMANX_WINDOW_T native_window;
	VC_RECT_T src_rect;
	VC_RECT_T dst_rect;

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

	this->m_display = eglGetDisplay( EGL_DEFAULT_DISPLAY );
	if ( this->m_display == EGL_NO_DISPLAY )
	{
		std::cerr << "ogEGLWindow::ogEGLWindow | eglGetDisplay returned EGL_NO_DISPLAY" << std::endl;
		exit( EXIT_FAILURE );
	}
	
	int major, minor;
	success = eglInitialize( this->m_display, &major, &minor );
	if ( success = EGL_FALSE )
	{
		std::cerr << "ogEGLWindow::ogEGLWindow | eglInitialize returned EGL_FALSE" << std::endl;
		exit( EXIT_FAILURE );
	}

	this->m_config_shptr->chooseConfig( this->m_display );

	success = eglBindAPI( EGL_OPENGL_ES_API );
	if ( success = EGL_FALSE )
	{
		std::cerr << "ogEGLWindow::ogEGLWindow | eglBindAPI returned EGL_FALSE" << std::endl;
		exit( EXIT_FAILURE );
	}

	this->m_context = eglCreateContext( this->m_display, this->m_config_shptr->getConfig(), EGL_NO_CONTEXT, ar_context_attributes );
	if ( success = EGL_FALSE )
	{
		std::cerr << "ogEGLWindow::ogEGLWindow | eglCreateContext returned EGL_FALSE" << std::endl;
		exit( EXIT_FAILURE );
	}

	src_rect.x = 0; src_rect.y = 0;
	src_rect.width = this->m_width << 16;
	src_rect.height = this->m_height << 16;

	dst_rect.x = 0; dst_rect.y = 0;
	dst_rect.width = this->m_width;
	dst_rect.height = this->m_height;

	this->m_dispmanx_display = vc_dispmanx_display_open( 0 );
	this->m_dispmanx_update = vc_dispmanx_update_start( 0 );
	this->m_dispmanx_element = vc_dispmanx_element_add( 
			this->m_dispmanx_update, this->m_dispmanx_display, 
			0, &dst_rect, 0, &src_rect, 
			DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE );

	native_window.element = this->m_dispmanx_element;
	native_window.width = this->m_width;
	native_window.height = this->m_height;

	vc_dispmanx_update_submit_sync( this->m_dispmanx_update );

	this->m_surface = eglCreateWindowSurface( 
			this->m_display, this->m_config_shptr->getConfig(), 
			&native_window, NULL );

	assert( this->m_surface != EGL_NO_SURFACE );

	success = eglMakeCurrent( this->m_display, this->m_surface, this->m_surface, this->m_context );

} // ogEGLWindow::ogEGLWindow
Beispiel #26
0
void InitGraphics()
{
	bcm_host_init();
	int32_t success = 0;
	EGLBoolean result;
	EGLint num_config;

	static EGL_DISPMANX_WINDOW_T nativewindow;

	DISPMANX_ELEMENT_HANDLE_T dispman_element;
	DISPMANX_DISPLAY_HANDLE_T dispman_display;
	DISPMANX_UPDATE_HANDLE_T dispman_update;
	VC_RECT_T dst_rect;
	VC_RECT_T src_rect;

	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
	};

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

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

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

	// get an appropriate EGL frame buffer configuration
	result = eglChooseConfig(GDisplay, 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
	GContext = eglCreateContext(GDisplay, config, EGL_NO_CONTEXT, context_attributes);
	assert(GContext!=EGL_NO_CONTEXT);
	check();

	// create an EGL window surface
	success = graphics_get_display_size(0 /* LCD */, &GScreenWidth, &GScreenHeight);
	assert( success >= 0 );

	dst_rect.x = 0;
	dst_rect.y = 0;
	dst_rect.width = GScreenWidth;
	dst_rect.height = GScreenHeight;

	src_rect.x = 0;
	src_rect.y = 0;
	src_rect.width = GScreenWidth << 16;
	src_rect.height = GScreenHeight << 16;

	dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
	dispman_update = vc_dispmanx_update_start( 0 );

	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*/);

	nativewindow.element = dispman_element;
	nativewindow.width = GScreenWidth;
	nativewindow.height = GScreenHeight;
	vc_dispmanx_update_submit_sync( dispman_update );

	check();

	GSurface = eglCreateWindowSurface( GDisplay, config, &nativewindow, NULL );
	assert(GSurface != EGL_NO_SURFACE);
	check();

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

	// Set background color and clear buffers
	glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
	glClear( GL_COLOR_BUFFER_BIT );

	//load the test shaders
	GSimpleVS.LoadVertexShader("simplevertshader.glsl");
	GSimpleFS.LoadFragmentShader("simplefragshader.glsl");
	GSimpleProg.Create(&GSimpleVS,&GSimpleFS);
	check();
	glUseProgram(GSimpleProg.GetId());
	check();

	//create an ickle vertex buffer
	static const GLfloat quad_vertex_positions[] = {
		0.0f, 0.0f,	1.0f, 1.0f,
		1.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f
	};
	glGenBuffers(1, &GQuadVertexBuffer);
	check();
	glBindBuffer(GL_ARRAY_BUFFER, GQuadVertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex_positions), quad_vertex_positions, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	check();
}
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);
}
Beispiel #28
0
bool Window::initialize()
{
	bcm_host_init();
	
	m_pSDLWindow = SDL_CreateWindow("SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, 0);

	if (NULL == m_pSDLWindow)
	{
		return	false;
	}

	m_pDisplay	= eglGetDisplay(EGL_DEFAULT_DISPLAY);

	if (EGL_NO_DISPLAY == m_pDisplay)
	{
		Log::instance()->logError("Unable to get display %d", eglGetError());

		return	false;
	}

	EGLint	iMajor;
	EGLint	iMinor;

	if (EGL_FALSE == eglInitialize(m_pDisplay, &iMajor, &iMinor))
	{
		Log::instance()->logError("Unable to initialize EGL %d", eglGetError());

		return	false;
	}

	EGLint iConfigAttributes[]	=
	{
		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
		EGL_RED_SIZE, 8,
		EGL_GREEN_SIZE, 8,
		EGL_BLUE_SIZE, 8,
		EGL_ALPHA_SIZE, 8,
 		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
		EGL_NONE
	};

	EGLConfig	config;
	int			iConfigs;

	if (EGL_FALSE == eglChooseConfig(m_pDisplay, iConfigAttributes, &config, 1, &iConfigs))
	{
		Log::instance()->logError("Unable to choose config %d", eglGetError());

		return	false;
	}

	m_pContext	= eglCreateContext(m_pDisplay, config, EGL_NO_CONTEXT, NULL);

	if (EGL_NO_CONTEXT == m_pContext)
	{
		Log::instance()->logError("Unable to create context %d", eglGetError());

		return	false;
	}

    uint32_t iMaxWidth	= 0;
	uint32_t iMaxHeight	= 0;
	
	if (graphics_get_display_size(0, &iMaxWidth, &iMaxHeight) < 0)
	{
		Log::instance()->logError("Unable to get display size");
		
		return	false;
	}
	
#if SCALED_DISPLAY
	const GameHeader&	gameHeader	= System::getGameHeader();

	VC_RECT_T	src;

	src.x		= 0;
	src.y		= 0;
	src.width	= gameHeader.iScreenWidth << 16;
	src.height	= gameHeader.iScreenHeight << 16;        

	VC_RECT_T	dest;
	
	dest.x		= 0;
	dest.y		= 0;
	dest.width	= iMaxWidth;
	dest.height	= iMaxHeight;
	  
	DISPMANX_ELEMENT_HANDLE_T	element;
	DISPMANX_DISPLAY_HANDLE_T	display;
	DISPMANX_UPDATE_HANDLE_T	update;
	
	display	= vc_dispmanx_display_open(0);
	update	= vc_dispmanx_update_start(0);		 
	element	= vc_dispmanx_element_add(update, display, 0, &dest, 0, &src, DISPMANX_PROTECTION_NONE, NULL, NULL, 
		DISPMANX_NO_ROTATE);
	  
	m_window.element	= element;
	m_window.width		= gameHeader.iScreenWidth;
	m_window.height		= gameHeader.iScreenHeight;

	vc_dispmanx_update_submit_sync(update);
      
	m_pSurface	= eglCreateWindowSurface(m_pDisplay, config, &m_window, NULL);

	if (EGL_NO_SURFACE == m_pSurface)
	{
		Log::instance()->logError("Unable to create window surface %d", eglGetError());

		return	false;
	}

	if (EGL_FALSE == eglMakeCurrent(m_pDisplay, m_pSurface, m_pSurface, m_pContext))
	{
		Log::instance()->logError("Unable to set current context %d", eglGetError());

		return	false;
    }
#else
	VC_RECT_T	src;

	src.x		= 0;
	src.y		= 0;
	src.width	= iMaxWidth;
	src.height	= iMaxHeight;

	VC_RECT_T	dest;
	
	dest.x		= 0;
	dest.y		= 0;
	dest.width	= iMaxWidth;
	dest.height	= iMaxHeight;
	  
	DISPMANX_ELEMENT_HANDLE_T	element;
	DISPMANX_DISPLAY_HANDLE_T	display;
	DISPMANX_UPDATE_HANDLE_T	update;
	
	display	= vc_dispmanx_display_open(0);
	update	= vc_dispmanx_update_start(0);		 
	element	= vc_dispmanx_element_add(update, display, 0, &dest, 0, &src, DISPMANX_PROTECTION_NONE, NULL, NULL, 
		DISPMANX_NO_ROTATE);
	  
	m_window.element	= element;
	m_window.width		= iMaxWidth;
	m_window.height		= iMaxHeight;

	vc_dispmanx_update_submit_sync(update);
      
	m_pSurface	= eglCreateWindowSurface(m_pDisplay, config, &m_window, NULL);

	if (EGL_NO_SURFACE == m_pSurface)
	{
		Log::instance()->logError("Unable to create window surface %d", eglGetError());

		return	false;
	}

	if (EGL_FALSE == eglMakeCurrent(m_pDisplay, m_pSurface, m_pSurface, m_pContext))
	{
		Log::instance()->logError("Unable to set current context %d", eglGetError());

		return	false;
    }

	const GameHeader&	gameHeader	= System::getUpdateableGameHeader();
    
	gameHeader.iScreenWidth		= iMaxWidth;
	gameHeader.iScreenHeight	= iMaxHeight;
#endif
    
	// Set swap interval
	if (EGL_FALSE == eglSwapInterval(m_pDisplay, 1))
	{
		Log::instance()->logError("Unable to set swap interval context");
	}

	return	true;
}
Beispiel #29
0
int piInitVideo()
{
	bcm_host_init();

	// get an EGL display connection
	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
	if (display == EGL_NO_DISPLAY) {
		fprintf(stderr, "eglGetDisplay() failed: EGL_NO_DISPLAY\n");
		return 0;
	}

	// initialize the EGL display connection
	EGLBoolean result = eglInitialize(display, NULL, NULL);
	if (result == EGL_FALSE) {
		fprintf(stderr, "eglInitialize() failed: EGL_FALSE\n");
		return 0;
	}

	// get an appropriate EGL frame buffer configuration
	EGLint numConfig;
	EGLConfig config;
	static const EGLint attributeList[] = {
		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, attributeList, &config, 1, &numConfig);
	if (result == EGL_FALSE) {
		fprintf(stderr, "eglChooseConfig() failed: EGL_FALSE\n");
		return 0;
	}

	result = eglBindAPI(EGL_OPENGL_ES_API);
	if (result == EGL_FALSE) {
		fprintf(stderr, "eglBindAPI() failed: EGL_FALSE\n");
		return 0;
	}

	// create an EGL rendering context
	static const EGLint contextAttributes[] = {
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};
	context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
	if (context == EGL_NO_CONTEXT) {
		fprintf(stderr, "eglCreateContext() failed: EGL_NO_CONTEXT\n");
		return 0;
	}

	// create an EGL window surface
	int32_t success = graphics_get_display_size(0, &screenWidth, &screenHeight);
	if (result < 0) {
		fprintf(stderr, "graphics_get_display_size() failed: < 0\n");
		return 0;
	}

	fprintf(stderr, "Width/height: %d/%d\n", screenWidth, screenHeight);

	VC_RECT_T dstRect;
	dstRect.x = 0;
	dstRect.y = 0;
	dstRect.width = screenWidth;
	dstRect.height = screenHeight;

	VC_RECT_T srcRect;
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.width = screenWidth << 16;
	srcRect.height = screenHeight << 16;

	DISPMANX_DISPLAY_HANDLE_T dispManDisplay = vc_dispmanx_display_open(0);
	DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);
	DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate,
		dispManDisplay, 0, &dstRect, 0, &srcRect,
		DISPMANX_PROTECTION_NONE, NULL, NULL, DISPMANX_NO_ROTATE);

	nativeWindow.element = dispmanElement;
	nativeWindow.width = screenWidth;
	nativeWindow.height = screenHeight;
	vc_dispmanx_update_submit_sync(dispmanUpdate);

	fprintf(stderr, "Initializing window surface...\n");

	surface = eglCreateWindowSurface(display, config, &nativeWindow, NULL);
	if (surface == EGL_NO_SURFACE) {
		fprintf(stderr, "eglCreateWindowSurface() failed: EGL_NO_SURFACE\n");
		return 0;
	}

	fprintf(stderr, "Connecting context to surface...\n");

	// connect the context to the surface
	result = eglMakeCurrent(display, surface, surface, context);
	if (result == EGL_FALSE) {
		fprintf(stderr, "eglMakeCurrent() failed: EGL_FALSE\n");
		return 0;
	}

	fprintf(stderr, "Initializing shaders...\n");

	// Init shader resources
	memset(&shader, 0, sizeof(ShaderInfo));
	shader.program = createProgram(vertexShaderSrc, fragmentShaderSrc);
	if (!shader.program) {
		fprintf(stderr, "createProgram() failed\n");
		return 0;
	}

	fprintf(stderr, "Initializing textures/buffers...\n");

	shader.a_position	= glGetAttribLocation(shader.program,	"a_position");
	shader.a_texcoord	= glGetAttribLocation(shader.program,	"a_texcoord");
	shader.u_vp_matrix	= glGetUniformLocation(shader.program,	"u_vp_matrix");
	shader.u_texture	= glGetUniformLocation(shader.program,	"u_texture");

	glGenTextures(1, textures);
	glBindTexture(GL_TEXTURE_2D, textures[0]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);

	glGenBuffers(3, buffers);
	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
	glBufferData(GL_ARRAY_BUFFER, kVertexCount * sizeof(GLfloat) * 3, vertices, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
	glBufferData(GL_ARRAY_BUFFER, kVertexCount * sizeof(GLfloat) * 2, uvs, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, kIndexCount * sizeof(GL_UNSIGNED_SHORT), indices, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_DITHER);

	float sx = 1.0f;
	float sy = 1.0f;
	float zoom = (float)ZOOM;

	// Screen aspect ratio adjustment
	float a = (float)screenWidth / screenHeight;
	float a0 = (float)WIDTH / (float)HEIGHT;

	if (a > a0) {
		sx = a0/a;
	} else {
		sy = a/a0;
	}

	setOrtho(projection, -0.5f, +0.5f, +0.5f, -0.5f, -1.0f, 1.0f,
		sx * zoom, sy * zoom);

	fprintf(stderr, "Setting up screen...\n");

	msxScreenPitch = WIDTH * BIT_DEPTH / 8;
	msxScreen = (char*)calloc(1, BIT_DEPTH / 8 * TEX_WIDTH * TEX_HEIGHT);
	if (!msxScreen) {
		fprintf(stderr, "Error allocating screen texture\n");
		return 0;
	}

	fprintf(stderr, "Initializing SDL video...\n");

	// We're doing our own video rendering - this is just so SDL-based keyboard
	// can work
	sdlScreen = SDL_SetVideoMode(0, 0, 0, 0);

	return 1;
}
Beispiel #30
0
/***********************************************************
 * Name: init_egl
 *
 * Arguments:
 *       CUBE_STATE_T *state - holds OGLES model info
 *
 * Description: Sets the display, OpenGL|ES context and screen stuff
 *
 * Returns: void
 *
 ***********************************************************/
static void init_egl(void)
{
   int32_t success = 0;
   EGLBoolean result;
   EGLint num_config;

   static EGL_DISPMANX_WINDOW_T nativewindow;

   DISPMANX_ELEMENT_HANDLE_T dispman_element;
   DISPMANX_DISPLAY_HANDLE_T dispman_display;
   DISPMANX_UPDATE_HANDLE_T dispman_update;
   VC_RECT_T dst_rect;
   VC_RECT_T src_rect;

   static const EGLint attribute_list[] =
   {
      EGL_RED_SIZE, 8,
      EGL_GREEN_SIZE, 8,
      EGL_BLUE_SIZE, 8,
      EGL_ALPHA_SIZE, 8,
      EGL_DEPTH_SIZE, 16,
      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
      EGL_NONE
   };

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

   EGLConfig config;

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

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

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

   // bind the gles api to this thread - this is default so not required
   result = eglBindAPI(EGL_OPENGL_ES_API);
   assert(EGL_FALSE != result);

   // create an EGL rendering context
   // select es 1.x or 2.x based on user option
   context_attributes[1] = state->useGLES2 + 1;
   state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
   assert(state->context!=EGL_NO_CONTEXT);

   // create an EGL window surface
   success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
   assert( success >= 0 );

   dst_rect.x = 0;
   dst_rect.y = 0;
   dst_rect.width = state->screen_width;
   dst_rect.height = state->screen_height;

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

   dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
   dispman_update = vc_dispmanx_update_start( 0 );

   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*/, 0/*transform*/);

   nativewindow.element = dispman_element;
   nativewindow.width = state->screen_width;
   nativewindow.height = state->screen_height;
   vc_dispmanx_update_submit_sync( dispman_update );

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

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

   // default to no vertical sync but user option may turn it on
   result = eglSwapInterval(state->display, state->useVSync );
   assert(EGL_FALSE != result);

   // Set background color and clear buffers
   glClearColor(0.25f, 0.45f, 0.55f, 1.0f);

   // Enable back face culling.
   glEnable(GL_CULL_FACE);
   glFrontFace(GL_CCW);

   if (state->wantInfo) {
      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
	   
   }
}