From a15b78f5473843d115eb1381504223e4a021d5ec Mon Sep 17 00:00:00 2001 From: rachytski Date: Thu, 28 Apr 2011 19:24:22 +0300 Subject: [PATCH] implemented runtime opengl functionality checking. --- map/framework.cpp | 4 ++- platform/qtplatform.cpp | 2 +- qt/widgets.cpp | 9 ++++- qt_tstfrm/tstwidgets.cpp | 13 +++++-- yg/internal/opengl.cpp | 13 ++++++- yg/internal/opengl.hpp | 16 ++++++--- yg/internal/opengl_win32.cpp | 61 +++++++++++++++++++++++++------- yg/internal/opengl_win32.hpp | 11 ++++++ yg/yg_tests/screengl_test.cpp | 40 ++++++++++----------- yg/yg_tests/skin_loader_test.cpp | 2 +- yg/yg_tests/skin_test.cpp | 2 +- 11 files changed, 127 insertions(+), 46 deletions(-) diff --git a/map/framework.cpp b/map/framework.cpp index 753b06b8e5..17c5cab7d8 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -16,6 +16,8 @@ #include "../std/algorithm.hpp" #include "../version/version.hpp" +#include "../yg/internal/opengl.hpp" + #include "../base/start_mem_debug.hpp" @@ -263,7 +265,7 @@ void FrameWork::AddRedrawCommandSure() m_isBenchmarkInitialized(false), m_bgColor(0xEE, 0xEE, 0xDD, 0xFF), m_renderQueue(GetPlatform().SkinName(), - GetPlatform().IsMultiSampled(), + GetPlatform().IsMultiSampled() && yg::gl::g_isMultisamplingSupported, GetPlatform().DoPeriodicalUpdate(), GetPlatform().PeriodicalUpdateInterval(), GetPlatform().IsBenchmarking(), diff --git a/platform/qtplatform.cpp b/platform/qtplatform.cpp index 977d965176..d0a814ee72 100644 --- a/platform/qtplatform.cpp +++ b/platform/qtplatform.cpp @@ -384,7 +384,7 @@ public: bool IsBenchmarking() const { - bool res = true; + bool res = false; #ifndef OMIM_PRODUCTION if (res) { diff --git a/qt/widgets.cpp b/qt/widgets.cpp index 8bbbe0a3b0..3a3ec25564 100644 --- a/qt/widgets.cpp +++ b/qt/widgets.cpp @@ -31,6 +31,12 @@ namespace qt #ifdef OMIM_OS_WINDOWS win32::InitOpenGL(); #endif + + if (!yg::gl::CheckExtensionSupport()) + { + /// TODO: Show "Please Update Drivers" dialog and close the program. + } + m_renderContext = shared_ptr(new qt::gl::RenderContext(this)); m_resourceManager = make_shared_ptr(new yg::ResourceManager( 50000 * sizeof(yg::gl::Vertex), @@ -48,7 +54,8 @@ namespace qt GetPlatform().ReadPathForFile("fonts_whitelist.txt").c_str(), GetPlatform().ReadPathForFile("fonts_blacklist.txt").c_str(), 2000000, - yg::Rt8Bpp)); + yg::Rt8Bpp, + !yg::gl::g_isBufferObjectsSupported)); m_resourceManager->addFonts(GetPlatform().GetFontNames()); diff --git a/qt_tstfrm/tstwidgets.cpp b/qt_tstfrm/tstwidgets.cpp index 352c051674..f6cd81df52 100644 --- a/qt_tstfrm/tstwidgets.cpp +++ b/qt_tstfrm/tstwidgets.cpp @@ -9,9 +9,10 @@ #include "../yg/renderbuffer.hpp" #include "../yg/resource_manager.hpp" -#ifdef OMIM_OS_WINDOWS +#include "../yg/internal/opengl.hpp" +/*#ifdef OMIM_OS_WINDOWS #include "../yg/internal/opengl_win32.hpp" -#endif +#endif*/ #include "../platform/platform.hpp" @@ -36,6 +37,11 @@ void GLDrawWidget::initializeGL() win32::InitOpenGL(); #endif + if (!yg::gl::CheckExtensionSupport()) + { + /// TODO: Show "Please Update Drivers" dialog and close the program. + } + m_primaryContext = make_shared_ptr(new qt::gl::RenderContext(this)); m_resourceManager = make_shared_ptr(new yg::ResourceManager( @@ -53,7 +59,8 @@ void GLDrawWidget::initializeGL() GetPlatform().ReadPathForFile("fonts_whitelist.txt").c_str(), GetPlatform().ReadPathForFile("fonts_blacklist.txt").c_str(), 2000000, - yg::Rt8Bpp)); + yg::Rt8Bpp, + !yg::gl::g_isBufferObjectsSupported)); m_resourceManager->addFonts(GetPlatform().GetFontNames()); diff --git a/yg/internal/opengl.cpp b/yg/internal/opengl.cpp index 77a896c4fc..72435072db 100644 --- a/yg/internal/opengl.cpp +++ b/yg/internal/opengl.cpp @@ -10,8 +10,19 @@ namespace yg { - namespace ogl + namespace gl { + bool g_isBufferObjectsSupported = true; + bool g_isFramebufferSupported = true; + bool g_isRenderbufferSupported = true; + bool g_isMultisamplingSupported = true; + + bool CheckExtensionSupport() + { + /// this functionality must be supported + return (g_isFramebufferSupported && g_isRenderbufferSupported); + } + void LogError(char const * err, my::SrcPoint const & srcPt) { if (err) diff --git a/yg/internal/opengl.hpp b/yg/internal/opengl.hpp index 902554b8c3..0603585bd8 100644 --- a/yg/internal/opengl.hpp +++ b/yg/internal/opengl.hpp @@ -31,17 +31,25 @@ namespace yg { - namespace ogl + namespace gl { + extern bool g_isBufferObjectsSupported; + extern bool g_isFramebufferSupported; + extern bool g_isRenderbufferSupported; + extern bool g_isMultisamplingSupported; + + /// return false to terminate program + bool CheckExtensionSupport(); + void CheckError(my::SrcPoint const & srcPt); void CheckEGLError(my::SrcPoint const & srcPt); } } #ifdef DEBUG -#define OGLCHECK(f) do {f; yg::ogl::CheckError(SRC());} while(false) -#define OGLCHECKAFTER yg::ogl::CheckError(SRC()) -#define EGLCHECK do {yg::ogl::CheckEGLError(SRC());} while(false) +#define OGLCHECK(f) do {f; yg::gl::CheckError(SRC());} while(false) +#define OGLCHECKAFTER yg::gl::CheckError(SRC()) +#define EGLCHECK do {yg::gl::CheckEGLError(SRC());} while(false) #else #define OGLCHECK(f) f #define OGLCHECKAFTER diff --git a/yg/internal/opengl_win32.cpp b/yg/internal/opengl_win32.cpp index 350c2d8bc3..961ce87bbd 100644 --- a/yg/internal/opengl_win32.cpp +++ b/yg/internal/opengl_win32.cpp @@ -13,8 +13,8 @@ PFNGLGENBUFFERSPROC glGenBuffers; PFNGLBUFFERDATAPROC glBufferData; PFNGLBUFFERSUBDATAPROC glBufferSubData; PFNGLDELETEBUFFERSPROC glDeleteBuffers; -PFNGLACTIVETEXTUREPROC glActiveTexture; -PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; +//PFNGLACTIVETEXTUREPROC glActiveTexture; +//PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; @@ -39,7 +39,7 @@ namespace win32 if (p == 0) { DWORD const err = ::GetLastError(); - LOG(LCRITICAL, ("OpenGL extension function ", name, " not found. Last error = ", err)); + LOG(LINFO, ("OpenGL extension function ", name, " not found. Last error = ", err)); } return reinterpret_cast(p); } @@ -48,27 +48,62 @@ namespace win32 { HMODULE hInst = 0; + /// buffer objects extensions + glBindBuffer = GetGLProc(hInst, "glBindBuffer"); glGenBuffers = GetGLProc(hInst, "glGenBuffers"); glBufferData = GetGLProc(hInst, "glBufferData"); glBufferSubData = GetGLProc(hInst, "glBufferSubData"); glDeleteBuffers = GetGLProc(hInst, "glDeleteBuffers"); - glActiveTexture = GetGLProc(hInst, "glActiveTexture"); - glClientActiveTexture = GetGLProc(hInst, "glClientActiveTexture"); + glMapBuffer = GetGLProc(hInst, "glMapBuffer"); + glUnmapBuffer = GetGLProc(hInst, "glUnmapBuffer"); + + yg::gl::g_isBufferObjectsSupported = &glBindBuffer + && &glGenBuffers + && &glBufferData + && &glBufferSubData + && &glDeleteBuffers + && &glMapBuffer + && &glUnmapBuffer; + +// glActiveTexture = GetGLProc(hInst, "glActiveTexture"); +// glClientActiveTexture = GetGLProc(hInst, "glClientActiveTexture"); + + /// framebuffers extensions + glBindFramebuffer = GetGLProc(hInst, "glBindFramebuffer"); glFramebufferTexture2D = GetGLProc(hInst, "glFramebufferTexture2D"); glFramebufferRenderbuffer = GetGLProc(hInst, "glFramebufferRenderbuffer"); glGenFramebuffers = GetGLProc(hInst, "glGenFramebuffers"); glDeleteFramebuffers = GetGLProc(hInst, "glDeleteFramebuffers"); - glBindRenderbufferEXT = GetGLProc(hInst, "glBindRenderbufferEXT"); - glGenRenderbuffers = GetGLProc(hInst, "glGenRenderbuffers"); - glRenderbufferStorageEXT = GetGLProc(hInst, "glRenderbufferStorageEXT"); - glDeleteRenderbuffersEXT = GetGLProc(hInst, "glDeleteRenderbuffersEXT"); - glMapBuffer = GetGLProc(hInst, "glMapBuffer"); - glUnmapBuffer = GetGLProc(hInst, "glUnmapBuffer"); - glBlitFramebuffer = GetGLProc(hInst, "glBlitFramebuffer"); - glRenderbufferStorageMultisample = GetGLProc(hInst, "glRenderbufferStorageMultisample"); glCheckFramebufferStatusEXT = GetGLProc(hInst, "glCheckFramebufferStatusEXT"); + glBlitFramebuffer = GetGLProc(hInst, "glBlitFramebuffer"); + + yg::gl::g_isFramebufferSupported = &glBindFrameBuffer + && &glFramebufferTexture2D + && &glFramebufferRenderbuffer + && &glGenFramebuffers + && &glDeleteFramebuffers + && &glCheckFramebufferStatusEXT + && &glBlitFramebuffer; + + /// renderbuffer extensions + + glGenRenderbuffers = GetGLProc(hInst, "glGenRenderbuffers"); + glDeleteRenderbuffersEXT = GetGLProc(hInst, "glDeleteRenderbuffersEXT"); + glBindRenderbufferEXT = GetGLProc(hInst, "glBindRenderbufferEXT"); + glRenderbufferStorageEXT = GetGLProc(hInst, "glRenderbufferStorageEXT"); + + yg::gl::g_isRenderbufferSupported = &glGenRenderbuffers + && &glDeleteRenderbuffersEXT + && &BindRenderbufferEXT + && &RenderbufferStorageEXT; + + /// multisampling extensions + + glRenderbufferStorageMultisample = GetGLProc(hInst, "glRenderbufferStorageMultisample"); + + yg::gl::g_isMultisamplingSupported = &glRenderbufferStorageMultisample; } } diff --git a/yg/internal/opengl_win32.hpp b/yg/internal/opengl_win32.hpp index 40f01333e5..dd883ff6db 100644 --- a/yg/internal/opengl_win32.hpp +++ b/yg/internal/opengl_win32.hpp @@ -30,6 +30,17 @@ extern PFNGLMAPBUFFERPROC glMapBuffer; extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; +namespace yg +{ + namespace gl + { + extern bool g_isBufferObjectsSupported; + extern bool g_isFramebufferSupported; + extern bool g_isRenderbufferSupported; + extern bool g_isMultisamplingSupported; + } +} + namespace win32 { void InitOpenGL(); diff --git a/yg/yg_tests/screengl_test.cpp b/yg/yg_tests/screengl_test.cpp index 43d84651ee..8d3d71ba3f 100644 --- a/yg/yg_tests/screengl_test.cpp +++ b/yg/yg_tests/screengl_test.cpp @@ -954,11 +954,11 @@ namespace } }; -// UNIT_TEST_GL(TestDrawPolyOverflow); + UNIT_TEST_GL(TestDrawPolyOverflow); UNIT_TEST_GL(TestDrawText); -// UNIT_TEST_GL(TestDrawSingleSymbol); -// UNIT_TEST_GL(TestDrawEmptySymbol); -// UNIT_TEST_GL(TestDrawSingleSymbolAndSolidPath); + UNIT_TEST_GL(TestDrawSingleSymbol); + UNIT_TEST_GL(TestDrawEmptySymbol); + UNIT_TEST_GL(TestDrawSingleSymbolAndSolidPath); UNIT_TEST_GL(TestDrawString); UNIT_TEST_GL(TestDrawStringWithFixedFont); UNIT_TEST_GL(TestDrawStringWithColor); @@ -970,21 +970,21 @@ namespace UNIT_TEST_GL(TestDrawTextOverflow); UNIT_TEST_GL(TestDrawTextFiltering); UNIT_TEST_GL(TestDrawRandomTextFiltering); -// UNIT_TEST_GL(TestDrawSGIConvex); -// UNIT_TEST_GL(TestDrawPoly); -// UNIT_TEST_GL(TestDrawSolidRect); -// UNIT_TEST_GL(TestDrawPathWithSkinPageMiss); + UNIT_TEST_GL(TestDrawSGIConvex); + UNIT_TEST_GL(TestDrawPoly); + UNIT_TEST_GL(TestDrawSolidRect); + UNIT_TEST_GL(TestDrawPathWithSkinPageMiss); // UNIT_TEST_GL(TestDrawPathWithOffset); -// UNIT_TEST_GL(TestDrawPathJoin); -// UNIT_TEST_GL(TestDrawPathSolid1PX); -// UNIT_TEST_GL(TestDrawPathSolid2PX); -// UNIT_TEST_GL(TestDrawPathSolid); -// UNIT_TEST_GL(TestDrawSector); -// UNIT_TEST_GL(TestDrawPathSolidDiffWidth); -// UNIT_TEST_GL(TestDrawPathSolidWithZ); -// UNIT_TEST_GL(TestDrawPathSolidWithClipRect); -// UNIT_TEST_GL(TestDrawUtilsRect); -// UNIT_TEST_GL(TestDrawUtilsRectFilledTexture); -// UNIT_TEST_GL(TestDrawSymbolFiltering); -// UNIT_TEST_GL(TestDrawCircle); + UNIT_TEST_GL(TestDrawPathJoin); + UNIT_TEST_GL(TestDrawPathSolid1PX); + UNIT_TEST_GL(TestDrawPathSolid2PX); + UNIT_TEST_GL(TestDrawPathSolid); + UNIT_TEST_GL(TestDrawSector); + UNIT_TEST_GL(TestDrawPathSolidDiffWidth); + UNIT_TEST_GL(TestDrawPathSolidWithZ); + UNIT_TEST_GL(TestDrawPathSolidWithClipRect); + UNIT_TEST_GL(TestDrawUtilsRect); + UNIT_TEST_GL(TestDrawUtilsRectFilledTexture); + UNIT_TEST_GL(TestDrawSymbolFiltering); + UNIT_TEST_GL(TestDrawCircle); } diff --git a/yg/yg_tests/skin_loader_test.cpp b/yg/yg_tests/skin_loader_test.cpp index fa97d1672d..6dd5326a96 100644 --- a/yg/yg_tests/skin_loader_test.cpp +++ b/yg/yg_tests/skin_loader_test.cpp @@ -8,6 +8,6 @@ UNIT_TEST(SkinLoaderTest_Main) { GL_TEST_START; - shared_ptr rm(new yg::ResourceManager(1000, 1000, 2, 1000, 1000, 2, 1000, 1000, 2, 128, 128, 15, "", "", "", 2000000, yg::Rt8Bpp)); + shared_ptr rm(new yg::ResourceManager(1000, 1000, 2, 1000, 1000, 2, 1000, 1000, 2, 128, 128, 15, "", "", "", 2000000, yg::Rt8Bpp, false)); /*yg::Skin * skin = */loadSkin(rm, "basic.skn", 2, 2); }; diff --git a/yg/yg_tests/skin_test.cpp b/yg/yg_tests/skin_test.cpp index b936692d79..3b57a68bc0 100644 --- a/yg/yg_tests/skin_test.cpp +++ b/yg/yg_tests/skin_test.cpp @@ -9,7 +9,7 @@ UNIT_TEST(SkinTest_Main) { GL_TEST_START; - shared_ptr rm(new yg::ResourceManager(100, 100, 1, 100, 100, 1, 100, 100, 1, 128, 128, 15, "", "", "", 2000000, yg::Rt8Bpp)); + shared_ptr rm(new yg::ResourceManager(100, 100, 1, 100, 100, 1, 100, 100, 1, 128, 128, 15, "", "", "", 2000000, yg::Rt8Bpp, false)); yg::Skin * skin = loadSkin(rm, "test.skn", 2, 2); double p0 [] = {1, 1};