瀏覽代碼

Adding FBDEV backend

Panagiotis Christopoulos Charitos 13 年之前
父節點
當前提交
49a65c1cf1
共有 7 個文件被更改,包括 265 次插入12 次删除
  1. 6 8
      CMakeLists.txt
  2. 30 0
      include/anki/core/NativeWindowEglFbdev.h
  3. 1 1
      include/anki/gl/Ogl.h
  4. 7 1
      src/CMakeLists.txt
  5. 0 2
      src/core/App.cpp
  6. 2 0
      src/core/CMakeLists.txt
  7. 219 0
      src/core/NativeWindowEglFbdev.cpp

+ 6 - 8
CMakeLists.txt

@@ -64,9 +64,14 @@ ELSE()
 ENDIF()
 
 # Window backend
-SET(ANKI_WINDOW_BACKEND "GLXX11" CACHE STRING "The window backend (GLXX11 or EGLX11 or DUMMY)")
+SET(ANKI_WINDOW_BACKEND "GLXX11" CACHE STRING "The window backend (GLXX11 or EGLX11 or EGLFBDEV or DUMMY)")
 MESSAGE("++ AnKi window backend: ${ANKI_WINDOW_BACKEND}")
 
+IF(ANKI_WINDOW_BACKEND STREQUAL "EGLFBDEV")
+	SET(ANKI_FBDEV_INCLUDE_DIRS CACHE STRING "The include paths for FBDEV")
+	SET(ANKI_FBDEV_LIB_DIRS CACHE STRING "The lib paths for FBDEV")
+ENDIF()
+
 #
 # Common compiler flags
 #
@@ -108,10 +113,8 @@ FIND_PACKAGE(Subversion 1.6 REQUIRED)
 
 IF(Subversion_FOUND)
 	Subversion_WC_INFO(${CMAKE_CURRENT_SOURCE_DIR} ER)
-	#ADD_DEFINITIONS("-DANKI_REVISION=${ER_WC_REVISION}")
 	SET(ANKI_REVISION ${ER_WC_REVISION})
 ELSE()
-	#ADD_DEFINITIONS("-DANKI_REVISION=-1")
 	SET(ANKI_REVISION "-1")
 ENDIF()
 
@@ -120,13 +123,8 @@ ENDIF()
 #
 SET(ANKI_VERSION_MAJOR 0)
 SET(ANKI_VERSION_MINOR 1)
-#ADD_DEFINITIONS("-DANKI_VERSION_MAJOR=${ANKI_VERSION_MAJOR}")
-#ADD_DEFINITIONS("-DANKI_VERSION_MINOR=${ANKI_VERSION_MINOR}")
 MESSAGE("++ AnKi version: ${ANKI_VERSION_MAJOR}.${ANKI_VERSION_MINOR}")
 
-#ADD_DEFINITIONS("-DANKI_WINDOW_BACKEND_${ANKI_WINDOW_BACKEND}")
-#ADD_DEFINITIONS("-DANKI_MATH_SIMD_${ANKI_MATH_SIMD}")
-
 CONFIGURE_FILE("include/anki/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h")
 INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h" DESTINATION "${INCLUDE_INSTALL_DIR}/anki")
 

+ 30 - 0
include/anki/core/NativeWindowEglFbdev.h

@@ -0,0 +1,30 @@
+#ifndef ANKI_CORE_NATIVE_WINDOW_EGL_FBDEV_H
+#define ANKI_CORE_NATIVE_WINDOW_EGL_FBDEV_H
+
+#include "anki/core/NativeWindow.h"
+#include <EGL/egl.h>
+#include <GLES3/gl3.h>
+
+namespace anki {
+
+/// Native window implementation for EGL & FBDEV
+struct NativeWindowImpl
+{
+	EGLDisplay display = EGL_NO_DISPLAY;
+	EGLSurface surface = EGL_NO_SURFACE;
+	EGLContext context = EGL_NO_CONTEXT;
+	EGLNativeWindowType fbwin = nullptr;
+
+	~NativeWindowImpl()
+	{
+		destroy();
+	}
+
+	void create(NativeWindowInitializer& init);
+	void destroy();
+};
+
+} // end namespace anki
+
+#endif
+

+ 1 - 1
include/anki/gl/Ogl.h

@@ -19,7 +19,7 @@
 
 #	define ANKI_GL_NON_SHARABLE_CHECK() \
 		ANKI_ASSERT(creationThreadId == std::this_thread::get_id() \
-			&& "FBO can be used only from the creation thread")
+			&& "Object can be used only from the creation thread")
 #else
 #	define ANKI_GL_NON_SHARABLE
 

+ 7 - 1
src/CMakeLists.txt

@@ -12,7 +12,13 @@ ENDFOREACH()
 
 ADD_LIBRARY(anki Dummy.cpp)
 
-TARGET_LINK_LIBRARIES(anki ${ANKI_LIBS} ankiglew ankitinyxml2 ankilua ankibullet ${_ANKI_LIBPNG} GL)
+IF(ANKI_WINDOW_BACKEND STREQUAL "GLXX11")
+	SET(ANKI_LIBS ${ANKI_LIBS} ankiglew GL)
+ELSE()
+	SET(ANKI_LIBS ${ANKI_LIBS} GLESv2 EGL)
+ENDIF()
+
+TARGET_LINK_LIBRARIES(anki ${ANKI_LIBS} ankitinyxml2 ankilua ankibullet ${_ANKI_LIBPNG})
 
 SET_TARGET_PROPERTIES(anki PROPERTIES LINKER_LANGUAGE CXX)
 

+ 0 - 2
src/core/App.cpp

@@ -5,7 +5,6 @@
 #include "anki/util/Filesystem.h"
 #include "anki/Config.h"
 #include "anki/util/Platform.h"
-#include <GL/glew.h>
 #include <cstring>
 #include <sstream>
 #include <iostream>
@@ -139,7 +138,6 @@ void App::printAppInfo()
 #endif
 	<< ", ";
 
-	msg << "GLEW " << glewGetString(GLEW_VERSION) << ", ";
 	msg << "build date " __DATE__ ", " << "rev " << ANKI_REVISION;
 
 	ANKI_LOGI(msg.str());

+ 2 - 0
src/core/CMakeLists.txt

@@ -4,6 +4,8 @@ IF(ANKI_WINDOW_BACKEND STREQUAL "GLXX11")
 	SET(ANKI_CORE_SOURCES ${ANKI_CORE_SOURCES} NativeWindowGlxX11.cpp)
 ELSEIF(ANKI_WINDOW_BACKEND STREQUAL "EGLX11")
 	SET(ANKI_CORE_SOURCES ${ANKI_CORE_SOURCES} NativeWindowEglX11.cpp)
+ELSEIF(ANKI_WINDOW_BACKEND STREQUAL "EGLFBDEV")
+	SET(ANKI_CORE_SOURCES ${ANKI_CORE_SOURCES} NativeWindowEglFbdev.cpp)
 ELSEIF(ANKI_WINDOW_BACKEND STREQUAL "DUMMY")
 	SET(ANKI_CORE_SOURCES ${ANKI_CORE_SOURCES} NativeWindowDummy.cpp)
 ELSE()

+ 219 - 0
src/core/NativeWindowEglFbdev.cpp

@@ -0,0 +1,219 @@
+#include "anki/core/NativeWindowEglFbdev.h"
+#include "anki/util/Exception.h"
+#include "anki/util/Vector.h"
+#include "anki/util/Array.h"
+#include "anki/util/StdTypes.h"
+
+namespace anki {
+
+//==============================================================================
+// NativeWindowImpl                                                            =
+//==============================================================================
+
+//==============================================================================
+void NativeWindowImpl::create(NativeWindowInitializer& init)
+{
+	// Create window
+	//
+	fbwin = (fbdev_window*)malloc(sizeof(fbdev_window));
+	if(fbwin == NULL)
+	{
+		throw ANKI_EXCEPTION("malloc() failed");
+	}
+	
+	fbwin->width = init.width;
+	fbwin->height = init.height;
+	
+	// EGL init
+	//
+	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+	if(display == EGL_NO_DISPLAY)
+	{
+		throw ANKI_EXCEPTION("Failed to create display");
+	}
+
+	int major, minor;
+	if(eglInitialize(display, &major, &minor) == EGL_FALSE)
+	{
+		throw ANKI_EXCEPTION("Failed to initialize EGL");
+	}
+
+	int maxConfigs;
+	if(eglGetConfigs(display, NULL, 0, &maxConfigs) == EGL_FALSE)
+	{
+		throw ANKI_EXCEPTION("Failed to query EGL configs");
+	}
+
+	if(maxConfigs < 1)
+	{
+		throw ANKI_EXCEPTION("Error in number of configs");
+	}
+
+	Vector<EGLConfig> configs(maxConfigs);
+
+	Array<int, 256> attribs;
+	U attr = 0;
+	attribs[attr++] = EGL_RENDERABLE_TYPE;
+	attribs[attr++] = EGL_OPENGL_ES2_BIT;
+
+	if(init.samplesCount > 1)
+	{
+		attribs[attr++] = EGL_SAMPLES;
+		attribs[attr++] = init.samplesCount;
+	}
+
+	attribs[attr++] = EGL_RED_SIZE;
+	attribs[attr++] = init.rgbaBits[0];
+	attribs[attr++] = EGL_GREEN_SIZE;
+	attribs[attr++] = init.rgbaBits[1];
+	attribs[attr++] = EGL_BLUE_SIZE;
+	attribs[attr++] = init.rgbaBits[2];
+	attribs[attr++] = EGL_ALPHA_SIZE;
+	attribs[attr++] = init.rgbaBits[3];
+
+	attribs[attr++] = EGL_DEPTH_SIZE;
+	attribs[attr++] = init.depthBits;
+	attribs[attr++] = EGL_STENCIL_SIZE;
+	attribs[attr++] = init.stencilBits;
+
+	attribs[attr++] = EGL_NONE;
+
+	int configsCount;
+	if(eglChooseConfig(display, attribs, &configs[0], maxConfigs, 
+		&configsCount) == EGL_FALSE)
+	{
+		throw ANKI_EXCEPTION("Failed to query required EGL configs");
+	}
+
+	if(configsCount == 0)
+	{
+		throw ANKI_EXCEPTION("No matching EGL configs found");
+	}
+
+	EGLConfig config_ = nullptr;
+	for(U i = 0; i < configsCount; i++)
+	{
+		EGLint value;
+		EGLConfig config = configs[i];
+
+		// Use this to explicitly check that the EGL config has the 
+		// expected color depths
+		eglGetConfigAttrib(display, config, EGL_RED_SIZE, &value);
+		if(value != init.rgbaBits[0]) 
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &value);
+		if(value != init.rgbaBits[1]) 
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &value);
+	    if(value != init.rgbaBits[2])
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &value);
+		if(value != init.rgbaBits[3])
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_SAMPLES, &value);
+		if(value != init.samplesCount)
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &value);
+		if(value != init.depthBits)
+		{
+			continue;
+		}
+
+		eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &value);
+		if(value != init.stencilBits)
+		{
+			continue;
+		}
+
+		// We found what we wanted
+		config_ = config;
+		break;
+	}
+
+	if(config_ == nullptr)
+	{
+		throw ANKI_EXCEPTION("Unable to find suitable EGL config");
+	}
+
+	// Surface
+	//
+	surface = eglCreateWindowSurface(display, config_, 
+		static_cast<EGLNativeWindowType>(fbwin), NULL);
+
+	if(surface == EGL_NO_SURFACE)
+	{
+		throw ANKI_EXCEPTION("Cannot create surface");
+	}
+
+	// Context
+	//
+	EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+
+	context = eglCreateContext(display, config_, EGL_NO_CONTEXT, 
+		ctxAttribs);
+
+	if(context == EGL_NO_CONTEXT)
+	{
+		throw ANKI_EXCEPTION("Cannot create context");
+	}
+
+	if(eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
+	{
+		throw ANKI_EXCEPTION("Cannot make the context current");
+	}
+}
+
+//==============================================================================
+void NativeWindowImpl::destroy()
+{
+	// XXX
+}
+
+
+//==============================================================================
+// NativeWindow                                                                =
+//==============================================================================
+
+//==============================================================================
+NativeWindow::~NativeWindow()
+{}
+
+//==============================================================================
+void NativeWindow::create(NativeWindowInitializer& initializer)
+{
+	impl.reset(new NativeWindowImpl);
+	impl->create(initializer);
+}
+
+//==============================================================================
+void NativeWindow::destroy()
+{
+	impl.reset();
+}
+
+//==============================================================================
+void NativeWindow::swapBuffers()
+{
+	ANKI_ASSERT(isCreated());
+	if(eglSwapBuffers(impl.display, impl.surface) == EGL_FALSE)
+	{
+		throw FUZZY_EXCEPTION("eglSwapBuffers() failed");
+	}
+}
+
+} // end namespace anki