From 2a4af1573b385f1c30ce376eee1385581d42beab Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 4 Mar 2012 12:46:55 +0100 Subject: auto adjust the screen resolution on first start. Closes #921 --- src/engine/client/backend_sdl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/engine/client/backend_sdl.h') diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index c6c2255a..305453f2 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -188,7 +188,7 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded ICommandProcessor *m_pProcessor; SGLContext m_GLContext; public: - virtual int Init(const char *pName, int Width, int Height, int FsaaSamples, int Flags); + virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags); virtual int Shutdown(); virtual void Minimize(); -- cgit 1.4.1 From b7e5bb54ad77545ae139115a1a64f9ebb7160006 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 10 Jun 2012 12:14:41 +0200 Subject: fixed semaphore on macosx --- src/base/system.c | 26 ++++++++++++++------------ src/base/system.h | 26 ++++++++++++++------------ src/base/tl/threading.h | 24 +++++++++++++++--------- src/engine/client/backend_sdl.h | 10 ++++++++++ src/engine/client/client.h | 2 -- src/engine/client/graphics.cpp | 14 ++++++++++++++ 6 files changed, 67 insertions(+), 35 deletions(-) (limited to 'src/engine/client/backend_sdl.h') diff --git a/src/base/system.c b/src/base/system.c index 7f98efe1..1c4d3a48 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -505,18 +505,20 @@ void lock_release(LOCK lock) #endif } -#if defined(CONF_FAMILY_UNIX) -void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); } -void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); } -void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); } -void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); } -#elif defined(CONF_FAMILY_WINDOWS) -void semaphore_init(SEMAPHORE *sem) { *sem = CreateSemaphore(0, 0, 10000, 0); } -void semaphore_wait(SEMAPHORE *sem) { WaitForSingleObject((HANDLE)*sem, 0L); } -void semaphore_signal(SEMAPHORE *sem) { ReleaseSemaphore((HANDLE)*sem, 1, NULL); } -void semaphore_destroy(SEMAPHORE *sem) { CloseHandle((HANDLE)*sem); } -#else - #error not implemented on this platform +#if !defined(CONF_PLATFORM_MACOSX) + #if defined(CONF_FAMILY_UNIX) + void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); } + void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); } + void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); } + void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); } + #elif defined(CONF_FAMILY_WINDOWS) + void semaphore_init(SEMAPHORE *sem) { *sem = CreateSemaphore(0, 0, 10000, 0); } + void semaphore_wait(SEMAPHORE *sem) { WaitForSingleObject((HANDLE)*sem, 0L); } + void semaphore_signal(SEMAPHORE *sem) { ReleaseSemaphore((HANDLE)*sem, 1, NULL); } + void semaphore_destroy(SEMAPHORE *sem) { CloseHandle((HANDLE)*sem); } + #else + #error not implemented on this platform + #endif #endif diff --git a/src/base/system.h b/src/base/system.h index b3588dbf..032cf785 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -403,20 +403,22 @@ void lock_release(LOCK lock); /* Group: Semaphores */ -#if defined(CONF_FAMILY_UNIX) - #include - typedef sem_t SEMAPHORE; -#elif defined(CONF_FAMILY_WINDOWS) - typedef void* SEMAPHORE; -#else - #error missing sempahore implementation +#if !defined(CONF_PLATFORM_MACOSX) + #if defined(CONF_FAMILY_UNIX) + #include + typedef sem_t SEMAPHORE; + #elif defined(CONF_FAMILY_WINDOWS) + typedef void* SEMAPHORE; + #else + #error missing sempahore implementation + #endif + + void semaphore_init(SEMAPHORE *sem); + void semaphore_wait(SEMAPHORE *sem); + void semaphore_signal(SEMAPHORE *sem); + void semaphore_destroy(SEMAPHORE *sem); #endif -void semaphore_init(SEMAPHORE *sem); -void semaphore_wait(SEMAPHORE *sem); -void semaphore_signal(SEMAPHORE *sem); -void semaphore_destroy(SEMAPHORE *sem); - /* Group: Timer */ #ifdef __GNUC__ /* if compiled with -pedantic-errors it will complain about long diff --git a/src/base/tl/threading.h b/src/base/tl/threading.h index dbf788cd..5caf8588 100644 --- a/src/base/tl/threading.h +++ b/src/base/tl/threading.h @@ -58,15 +58,21 @@ #error missing atomic implementation for this compiler #endif -class semaphore -{ - SEMAPHORE sem; -public: - semaphore() { semaphore_init(&sem); } - ~semaphore() { semaphore_destroy(&sem); } - void wait() { semaphore_wait(&sem); } - void signal() { semaphore_signal(&sem); } -}; +#if defined(CONF_PLATFORM_MACOSX) + /* + use semaphore provided by SDL on macosx + */ +#else + class semaphore + { + SEMAPHORE sem; + public: + semaphore() { semaphore_init(&sem); } + ~semaphore() { semaphore_destroy(&sem); } + void wait() { semaphore_wait(&sem); } + void signal() { semaphore_signal(&sem); } + }; +#endif class lock { diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index 305453f2..2ef04a1f 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -30,6 +30,16 @@ #include + class semaphore + { + SDL_sem *sem; + public: + semaphore() { sem = SDL_CreateSemaphore(0); } + ~semaphore() { SDL_DestroySemaphore(sem); } + void wait() { SDL_SemWait(sem); } + void signal() { SDL_SemPost(sem); } + }; + struct SGLContext { AGLContext m_Context; diff --git a/src/engine/client/client.h b/src/engine/client/client.h index d958b49a..87e2bc70 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -175,8 +175,6 @@ class CClient : public IClient, public CDemoPlayer::IListner class CHostLookup m_VersionServeraddr; } m_VersionInfo; - semaphore m_GfxRenderSemaphore; - semaphore m_GfxStateSemaphore; volatile int m_GfxState; static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); } void GraphicsThread(); diff --git a/src/engine/client/graphics.cpp b/src/engine/client/graphics.cpp index bf432356..8816e1ed 100644 --- a/src/engine/client/graphics.cpp +++ b/src/engine/client/graphics.cpp @@ -22,6 +22,20 @@ #include "graphics.h" +#if defined(CONF_PLATFORM_MACOSX) + + class semaphore + { + SDL_sem *sem; + public: + semaphore() { sem = SDL_CreateSemaphore(0); } + ~semaphore() { SDL_DestroySemaphore(sem); } + void wait() { SDL_SemWait(sem); } + void signal() { SDL_SemPost(sem); } + }; +#endif + + static CVideoMode g_aFakeModes[] = { {320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8}, {720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8}, -- cgit 1.4.1 From 678b6faceb8f8bd550de32b8fe59f7c34e2a3172 Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sun, 26 Aug 2012 20:02:04 +0200 Subject: Fixed threaded gfx and building on Mac OS X --- src/engine/client/backend_sdl.cpp | 3 +++ src/engine/client/backend_sdl.h | 52 +++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 7 deletions(-) (limited to 'src/engine/client/backend_sdl.h') diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index cb865bae..22c48e53 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -11,6 +11,9 @@ void CGraphicsBackend_Threaded::ThreadFunc(void *pUser) { + #ifdef CONF_PLATFORM_MACOSX + CAutoreleasePool AutoreleasePool; + #endif CGraphicsBackend_Threaded *pThis = (CGraphicsBackend_Threaded *)pUser; while(!pThis->m_Shutdown) diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index 2ef04a1f..619ba84d 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -28,7 +28,7 @@ static void GL_SwapBuffers(const SGLContext &Context) { SwapBuffers(Context.m_hDC); } #elif defined(CONF_PLATFORM_MACOSX) - #include + #include class semaphore { @@ -42,20 +42,58 @@ struct SGLContext { - AGLContext m_Context; + id m_Context; }; static SGLContext GL_GetCurrentContext() { SGLContext Context; - Context.m_Context = aglGetCurrentContext(); + Class NSOpenGLContextClass = (Class) objc_getClass("NSOpenGLContext"); + SEL selector = sel_registerName("currentContext"); + Context.m_Context = objc_msgSend((objc_object*) NSOpenGLContextClass, selector); return Context; } - static void GL_MakeCurrent(const SGLContext &Context) { aglSetCurrentContext(Context.m_Context); } - static void GL_ReleaseContext(const SGLContext &Context) { aglSetCurrentContext(NULL); } - static void GL_SwapBuffers(const SGLContext &Context) { aglSwapBuffers(Context.m_Context); } - + static void GL_MakeCurrent(const SGLContext &Context) + { + SEL selector = sel_registerName("makeCurrentContext"); + objc_msgSend(Context.m_Context, selector); + } + + static void GL_ReleaseContext(const SGLContext &Context) + { + Class NSOpenGLContextClass = (Class) objc_getClass("NSOpenGLContext"); + SEL selector = sel_registerName("clearCurrentContext"); + objc_msgSend((objc_object*) NSOpenGLContextClass, selector); + } + + static void GL_SwapBuffers(const SGLContext &Context) + { + SEL selector = sel_registerName("flushBuffer"); + objc_msgSend(Context.m_Context, selector); + } + + class CAutoreleasePool + { + private: + id m_Pool; + + public: + CAutoreleasePool() + { + Class NSAutoreleasePoolClass = (Class) objc_getClass("NSAutoreleasePool"); + m_Pool = class_createInstance(NSAutoreleasePoolClass, 0); + SEL selector = sel_registerName("init"); + objc_msgSend(m_Pool, selector); + } + + ~CAutoreleasePool() + { + SEL selector = sel_registerName("drain"); + objc_msgSend(m_Pool, selector); + } + }; + #elif defined(CONF_FAMILY_UNIX) #include -- cgit 1.4.1 From 71af97a5e30739577bde35db24ec9f160b0bea65 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 6 Oct 2012 23:31:02 +0200 Subject: fixed texture memory usage calculation in graphics threaded Conflicts: src/engine/client/graphics_threaded.cpp --- src/engine/client/backend_sdl.cpp | 46 +++++++++++++++++++++------ src/engine/client/backend_sdl.h | 28 +++++++++++++++-- src/engine/client/graphics_threaded.cpp | 55 ++++++++++++--------------------- src/engine/client/graphics_threaded.h | 16 ++++------ 4 files changed, 89 insertions(+), 56 deletions(-) (limited to 'src/engine/client/backend_sdl.h') diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index 5f57fa30..d99f765b 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -133,7 +133,7 @@ void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &St if(State.m_Texture >= 0 && State.m_Texture < CCommandBuffer::MAX_TEXTURES) { glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture]); + glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex); } else glDisable(GL_TEXTURE_2D); @@ -158,9 +158,14 @@ void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &St glOrtho(State.m_ScreenTL.x, State.m_ScreenBR.x, State.m_ScreenBR.y, State.m_ScreenTL.y, 1.0f, 10.f); } +void CCommandProcessorFragment_OpenGL::Cmd_Init(const SCommand_Init *pCommand) +{ + m_pTextureMemoryUsage = pCommand->m_pTextureMemoryUsage; +} + void CCommandProcessorFragment_OpenGL::Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand) { - glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot]); + glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot].m_Tex); glTexSubImage2D(GL_TEXTURE_2D, 0, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height, TexFormatToOpenGLFormat(pCommand->m_Format), GL_UNSIGNED_BYTE, pCommand->m_pData); mem_free(pCommand->m_pData); @@ -168,7 +173,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Update(const CCommandBuffer:: void CCommandProcessorFragment_OpenGL::Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand) { - glDeleteTextures(1, &m_aTextures[pCommand->m_Slot]); + glDeleteTextures(1, &m_aTextures[pCommand->m_Slot].m_Tex); + *m_pTextureMemoryUsage -= m_aTextures[pCommand->m_Slot].m_MemSize; } void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand) @@ -186,8 +192,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer:: default: StoreOglformat = GL_COMPRESSED_RGBA_ARB; } } - glGenTextures(1, &m_aTextures[pCommand->m_Slot]); - glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot]); + glGenTextures(1, &m_aTextures[pCommand->m_Slot].m_Tex); + glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot].m_Tex); if(pCommand->m_Flags&CCommandBuffer::TEXFLAG_NOMIPMAPS) { @@ -202,6 +208,18 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer:: gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, pCommand->m_Width, pCommand->m_Height, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData); } + // calculate memory usage + int Width = pCommand->m_Width; + int Height = pCommand->m_Height; + m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize; + while(Width > 2 && Height > 2) + { + Width>>=1; + Height>>=1; + m_aTextures[pCommand->m_Slot].m_MemSize += Width*Height*pCommand->m_PixelSize; + } + *m_pTextureMemoryUsage += m_aTextures[pCommand->m_Slot].m_MemSize; + mem_free(pCommand->m_pData); } @@ -273,12 +291,14 @@ void CCommandProcessorFragment_OpenGL::Cmd_Screenshot(const CCommandBuffer::SCom CCommandProcessorFragment_OpenGL::CCommandProcessorFragment_OpenGL() { mem_zero(m_aTextures, sizeof(m_aTextures)); + m_pTextureMemoryUsage = 0; } bool CCommandProcessorFragment_OpenGL::RunCommand(const CCommandBuffer::SCommand * pBaseCommand) { switch(pBaseCommand->m_Cmd) { + case CMD_INIT: Cmd_Init(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_TEXTURE_CREATE: Cmd_Texture_Create(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_TEXTURE_DESTROY: Cmd_Texture_Destroy(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_TEXTURE_UPDATE: Cmd_Texture_Update(static_cast(pBaseCommand)); break; @@ -487,11 +507,14 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Width, int *Height m_pProcessor = new CCommandProcessor_SDL_OpenGL; StartProcessor(m_pProcessor); - // issue a init command + // issue init commands for OpenGL and SDL CCommandBuffer CmdBuffer(1024, 512); - CCommandProcessorFragment_SDL::SCommand_Init Cmd; - Cmd.m_Context = m_GLContext; - CmdBuffer.AddCommand(Cmd); + CCommandProcessorFragment_OpenGL::SCommand_Init CmdOpenGL; + CmdOpenGL.m_pTextureMemoryUsage = &m_TextureMemoryUsage; + CmdBuffer.AddCommand(CmdOpenGL); + CCommandProcessorFragment_SDL::SCommand_Init CmdSDL; + CmdSDL.m_Context = m_GLContext; + CmdBuffer.AddCommand(CmdSDL); RunBuffer(&CmdBuffer); WaitForIdle(); @@ -517,6 +540,11 @@ int CGraphicsBackend_SDL_OpenGL::Shutdown() return 0; } +int CGraphicsBackend_SDL_OpenGL::MemoryUsage() const +{ + return m_TextureMemoryUsage; +} + void CGraphicsBackend_SDL_OpenGL::Minimize() { SDL_WM_IconifyWindow(); diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index 619ba84d..e1fc60b0 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -167,11 +167,32 @@ public: // takes care of opengl related rendering class CCommandProcessorFragment_OpenGL { - GLuint m_aTextures[CCommandBuffer::MAX_TEXTURES]; + struct CTexture + { + GLuint m_Tex; + int m_MemSize; + }; + CTexture m_aTextures[CCommandBuffer::MAX_TEXTURES]; + volatile int *m_pTextureMemoryUsage; + +public: + enum + { + CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM_OPENGL, + }; + + struct SCommand_Init : public CCommandBuffer::SCommand + { + SCommand_Init() : SCommand(CMD_INIT) {} + volatile int *m_pTextureMemoryUsage; + }; + +private: static int TexFormatToOpenGLFormat(int TexFormat); void SetState(const CCommandBuffer::SState &State); + void Cmd_Init(const SCommand_Init *pCommand); void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand); void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand); void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand); @@ -193,7 +214,7 @@ class CCommandProcessorFragment_SDL public: enum { - CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM, + CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM_SDL, CMD_SHUTDOWN, }; @@ -235,10 +256,13 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded SDL_Surface *m_pScreenSurface; ICommandProcessor *m_pProcessor; SGLContext m_GLContext; + volatile int m_TextureMemoryUsage; public: virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags); virtual int Shutdown(); + virtual int MemoryUsage() const; + virtual void Minimize(); virtual void Maximize(); virtual int WindowActive(); diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 8653b62a..751e4ad2 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -228,7 +228,7 @@ void CGraphics_Threaded::WrapClamp() int CGraphics_Threaded::MemoryUsage() const { - return m_TextureMemoryUsage; + return m_pBackend->MemoryUsage(); } void CGraphics_Threaded::MapScreen(float TopLeftX, float TopLeftY, float BottomRightX, float BottomRightY) @@ -293,8 +293,7 @@ int CGraphics_Threaded::UnloadTexture(int Index) Cmd.m_Slot = Index; m_pCommandBuffer->AddCommand(Cmd); - m_aTextures[Index].m_Next = m_FirstFreeTexture; - m_TextureMemoryUsage -= m_aTextures[Index].m_MemSize; + m_aTextures[Index] = m_FirstFreeTexture; m_FirstFreeTexture = Index; return 0; } @@ -307,6 +306,16 @@ static int ImageFormatToTexFormat(int Format) return CCommandBuffer::TEXFORMAT_RGBA; } +static int ImageFormatToPixelSize(int Format) +{ + switch(Format) + { + case CImageInfo::FORMAT_RGB: return 3; + case CImageInfo::FORMAT_ALPHA: return 1; + default: return 4; + } +} + int CGraphics_Threaded::LoadTextureRawSub(int TextureID, int x, int y, int Width, int Height, int Format, const void *pData) { @@ -319,13 +328,7 @@ int CGraphics_Threaded::LoadTextureRawSub(int TextureID, int x, int y, int Width Cmd.m_Format = ImageFormatToTexFormat(Format); // calculate memory usage - int PixelSize = 4; - if(Format == CImageInfo::FORMAT_RGB) - PixelSize = 3; - else if(Format == CImageInfo::FORMAT_ALPHA) - PixelSize = 1; - - int MemSize = Width*Height*PixelSize; + int MemSize = Width*Height*ImageFormatToPixelSize(Format); // copy texture data void *pTmpData = mem_alloc(MemSize, sizeof(void*)); @@ -345,13 +348,14 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const // grab texture int Tex = m_FirstFreeTexture; - m_FirstFreeTexture = m_aTextures[Tex].m_Next; - m_aTextures[Tex].m_Next = -1; + m_FirstFreeTexture = m_aTextureIndices[Tex]; + m_aTextureIndices[Tex] = -1; CCommandBuffer::SCommand_Texture_Create Cmd; Cmd.m_Slot = Tex; Cmd.m_Width = Width; Cmd.m_Height = Height; + Cmd.m_PixelSize = ImageFormatToPixelSize(Format); Cmd.m_Format = ImageFormatToTexFormat(Format); Cmd.m_StoreFormat = ImageFormatToTexFormat(StoreFormat); @@ -362,16 +366,8 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const if(g_Config.m_GfxTextureCompression) Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED; - // calculate memory usage - int PixelSize = 4; - if(Format == CImageInfo::FORMAT_RGB) - PixelSize = 3; - else if(Format == CImageInfo::FORMAT_ALPHA) - PixelSize = 1; - - int MemSize = Width*Height*PixelSize; - // copy texture data + int MemSize = Width*Height*Cmd.m_PixelSize; void *pTmpData = mem_alloc(MemSize, sizeof(void*)); mem_copy(pTmpData, pData, MemSize); Cmd.m_pData = pTmpData; @@ -379,17 +375,6 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const // m_pCommandBuffer->AddCommand(Cmd); - // calculate memory usage - int MemUsage = MemSize; - while(Width > 2 && Height > 2) - { - Width>>=1; - Height>>=1; - MemUsage += Width*Height*PixelSize; - } - - m_TextureMemoryUsage += MemUsage; - //mem_free(pTmpData); return Tex; } @@ -775,9 +760,9 @@ int CGraphics_Threaded::Init() // init textures m_FirstFreeTexture = 0; - for(int i = 0; i < MAX_TEXTURES; i++) - m_aTextures[i].m_Next = i+1; - m_aTextures[MAX_TEXTURES-1].m_Next = -1; + for(int i = 0; i < MAX_TEXTURES-1; i++) + m_aTextureIndices[i] = i+1; + m_aTextureIndices[MAX_TEXTURES-1] = -1; m_pBackend = CreateGraphicsBackend(); if(InitWindow() != 0) diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index e482f6e5..6b3963ee 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -57,7 +57,8 @@ public: { // commadn groups CMDGROUP_CORE = 0, // commands that everyone has to implement - CMDGROUP_PLATFORM = 10000, // commands specific to a platform + CMDGROUP_PLATFORM_OPENGL = 10000, // commands specific to a platform + CMDGROUP_PLATFORM_SDL = 20000, // CMD_NOP = CMDGROUP_CORE, @@ -211,6 +212,7 @@ public: int m_Width; int m_Height; + int m_PixelSize; int m_Format; int m_StoreFormat; int m_Flags; @@ -302,6 +304,8 @@ public: virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags) = 0; virtual int Shutdown() = 0; + virtual int MemoryUsage() const = 0; + virtual void Minimize() = 0; virtual void Maximize() = 0; virtual int WindowActive() = 0; @@ -351,15 +355,7 @@ class CGraphics_Threaded : public IEngineGraphics int m_InvalidTexture; - struct CTexture - { - int m_State; - int m_MemSize; - int m_Flags; - int m_Next; - }; - - CTexture m_aTextures[MAX_TEXTURES]; + int m_aTextureIndices[MAX_TEXTURES]; int m_FirstFreeTexture; int m_TextureMemoryUsage; -- cgit 1.4.1 From df5ab998c276e34a4870085d6ddafd812a9b1912 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 7 Oct 2012 11:22:49 +0200 Subject: readded texture resampling --- src/engine/client/backend_sdl.cpp | 76 ++++++++++++++++++++++++++++++--- src/engine/client/backend_sdl.h | 2 + src/engine/client/graphics_threaded.cpp | 37 +--------------- src/engine/client/graphics_threaded.h | 4 +- 4 files changed, 76 insertions(+), 43 deletions(-) (limited to 'src/engine/client/backend_sdl.h') diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index d99f765b..6fa6de01 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -100,6 +100,41 @@ int CCommandProcessorFragment_OpenGL::TexFormatToOpenGLFormat(int TexFormat) return GL_RGBA; } +unsigned char CCommandProcessorFragment_OpenGL::Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp) +{ + int Value = 0; + for(int x = 0; x < ScaleW; x++) + for(int y = 0; y < ScaleH; y++) + Value += pData[((v+y)*w+(u+x))*Bpp+Offset]; + return Value/(ScaleW*ScaleH); +} + +void *CCommandProcessorFragment_OpenGL::Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData) +{ + unsigned char *pTmpData; + int ScaleW = Width/NewWidth; + int ScaleH = Height/NewHeight; + + int Bpp = 3; + if(Format == CCommandBuffer::TEXFORMAT_RGBA) + Bpp = 4; + + pTmpData = (unsigned char *)mem_alloc(NewWidth*NewHeight*Bpp, 1); + + int c = 0; + for(int y = 0; y < NewHeight; y++) + for(int x = 0; x < NewWidth; x++, c++) + { + pTmpData[c*Bpp] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 0, ScaleW, ScaleH, Bpp); + pTmpData[c*Bpp+1] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 1, ScaleW, ScaleH, Bpp); + pTmpData[c*Bpp+2] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 2, ScaleW, ScaleH, Bpp); + if(Bpp == 4) + pTmpData[c*Bpp+3] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 3, ScaleW, ScaleH, Bpp); + } + + return pTmpData; +} + void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &State) { // blend @@ -179,6 +214,39 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Destroy(const CCommandBuffer: void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand) { + int Width = pCommand->m_Width; + int Height = pCommand->m_Height; + void *pTexData = pCommand->m_pData; + + // resample if needed + if(pCommand->m_Format == CCommandBuffer::TEXFORMAT_RGBA || pCommand->m_Format == CCommandBuffer::TEXFORMAT_RGB) + { + int MaxTexSize; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTexSize); + if(Width > MaxTexSize || Height > MaxTexSize) + { + do + { + Width>>=1; + Height>>=1; + } + while(Width > MaxTexSize || Height > MaxTexSize); + + void *pTmpData = Rescale(pCommand->m_Width, pCommand->m_Height, Width, Height, pCommand->m_Format, static_cast(pCommand->m_pData)); + mem_free(pTexData); + pTexData = pTmpData; + } + else if(Width > 16 && Height > 16 && (pCommand->m_Flags&CCommandBuffer::TEXFLAG_QUALITY) == 0) + { + Width>>=1; + Height>>=1; + + void *pTmpData = Rescale(pCommand->m_Width, pCommand->m_Height, Width, Height, pCommand->m_Format, static_cast(pCommand->m_pData)); + mem_free(pTexData); + pTexData = pTmpData; + } + } + int Oglformat = TexFormatToOpenGLFormat(pCommand->m_Format); int StoreOglformat = TexFormatToOpenGLFormat(pCommand->m_StoreFormat); @@ -199,18 +267,16 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer:: { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, pCommand->m_Width, pCommand->m_Height, 0, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData); + glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, pCommand->m_Width, pCommand->m_Height, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData); + gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, Width, Height, Oglformat, GL_UNSIGNED_BYTE, pTexData); } // calculate memory usage - int Width = pCommand->m_Width; - int Height = pCommand->m_Height; m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize; while(Width > 2 && Height > 2) { @@ -220,7 +286,7 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer:: } *m_pTextureMemoryUsage += m_aTextures[pCommand->m_Slot].m_MemSize; - mem_free(pCommand->m_pData); + mem_free(pTexData); } void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand) diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index e1fc60b0..e90f9455 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -189,6 +189,8 @@ public: private: static int TexFormatToOpenGLFormat(int TexFormat); + static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp); + static void *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData); void SetState(const CCommandBuffer::SState &State); diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 751e4ad2..7a2687c5 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -107,41 +107,6 @@ void CGraphics_Threaded::Rotate4(const CCommandBuffer::SPoint &rCenter, CCommand } } -unsigned char CGraphics_Threaded::Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp) -{ - int Value = 0; - for(int x = 0; x < ScaleW; x++) - for(int y = 0; y < ScaleH; y++) - Value += pData[((v+y)*w+(u+x))*Bpp+Offset]; - return Value/(ScaleW*ScaleH); -} - -unsigned char *CGraphics_Threaded::Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData) -{ - unsigned char *pTmpData; - int ScaleW = Width/NewWidth; - int ScaleH = Height/NewHeight; - - int Bpp = 3; - if(Format == CImageInfo::FORMAT_RGBA) - Bpp = 4; - - pTmpData = (unsigned char *)mem_alloc(NewWidth*NewHeight*Bpp, 1); - - int c = 0; - for(int y = 0; y < NewHeight; y++) - for(int x = 0; x < NewWidth; x++, c++) - { - pTmpData[c*Bpp] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 0, ScaleW, ScaleH, Bpp); - pTmpData[c*Bpp+1] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 1, ScaleW, ScaleH, Bpp); - pTmpData[c*Bpp+2] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 2, ScaleW, ScaleH, Bpp); - if(Bpp == 4) - pTmpData[c*Bpp+3] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 3, ScaleW, ScaleH, Bpp); - } - - return pTmpData; -} - CGraphics_Threaded::CGraphics_Threaded() { m_State.m_ScreenTL.x = 0; @@ -365,6 +330,8 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NOMIPMAPS; if(g_Config.m_GfxTextureCompression) Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED; + if(g_Config.m_GfxTextureQuality || Flags&TEXLOAD_NORESAMPLE) + Cmd.m_Flags |= CCommandBuffer::TEXFLAG_QUALITY; // copy texture data int MemSize = Width*Height*Cmd.m_PixelSize; diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 6b3963ee..809a383a 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -96,6 +96,7 @@ public: TEXFLAG_NOMIPMAPS = 1, TEXFLAG_COMPRESSED = 2, + TEXFLAG_QUALITY = 4, }; enum @@ -363,9 +364,6 @@ class CGraphics_Threaded : public IEngineGraphics void AddVertices(int Count); void Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints); - static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp); - static unsigned char *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData); - void KickCommandBuffer(); int IssueInit(); -- cgit 1.4.1