Fixed: #1053 Move mac screen mode retrieval to cocoa_adapter

This commit is contained in:
rti 2010-08-04 22:12:54 +02:00
parent b1fa58f06b
commit cc47fd2531
4 changed files with 79 additions and 95 deletions

View file

@ -1,91 +0,0 @@
#include "stdopengl.h"
#include <nel/misc/types_nl.h>
#ifdef NL_OS_MAC
#include <nel/3d/driver.h>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
using namespace std;
using namespace NLMISC;
using namespace NL3D;
namespace NL3D
{
static int bppFromDisplayMode(CGDisplayModeRef mode)
{
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
if(CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 32;
else if(CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 16;
return 0;
}
bool getMacModes(std::vector<GfxMode> &modes)
{
static const CGDisplayCount kMaxDisplays = 16;
CGDirectDisplayID display[kMaxDisplays];
CGDisplayCount numDisplays;
CGDisplayErr err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays);
if (err != CGDisplayNoErr)
{
nlwarning("Cannot get displays (%d)", err);
return false;
}
nldebug("3D: %d displays found", (int)numDisplays);
for (CGDisplayCount i = 0; i < numDisplays; ++i)
{
CGDirectDisplayID dspy = display[i];
CFArrayRef modeList = CGDisplayCopyAllDisplayModes(dspy, NULL);
if (modeList == NULL)
{
nlwarning("Display is invalid");
continue;
}
for (CFIndex j = 0; j < CFArrayGetCount(modeList); ++j)
{
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, j);
int bpp = bppFromDisplayMode(mode);
if (bpp >= 16)
{
int w = CGDisplayModeGetWidth(mode);
int h = CGDisplayModeGetHeight(mode);
// Add this mode
GfxMode mode;
mode.Width = (uint16)w;
mode.Height = (uint16)h;
mode.Depth = (uint8)bpp;
// frequency stays at 0 because on mac cocoa, display resolution
// is never really changed. if rendering resolution < display resolution
// cocoa interpolates and keeps the display at it's original resolution
mode.Frequency = 0;
modes.push_back (mode);
nldebug( " Display 0x%x: Mode %dx%d, %d BPP", dspy, w, h, bpp);
}
}
}
return true;
}
}
#endif

View file

@ -1581,10 +1581,7 @@ bool CDriverGL::getModes(std::vector<GfxMode> &modes)
modeIndex++; modeIndex++;
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
getMacModes(modes); NL3D::MAC::getModes(modes);
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)

View file

@ -70,6 +70,9 @@ bool setWindowStyle(nlWindow wnd, bool fullscreen);
/// mac specific stuff while calling CDriverGL::getCurrentScreenMode() /// mac specific stuff while calling CDriverGL::getCurrentScreenMode()
void getCurrentScreenMode(nlWindow wnd, GfxMode& mode); void getCurrentScreenMode(nlWindow wnd, GfxMode& mode);
/// mac specific stuff while calling CDriverGL::getModes()
bool getModes(std::vector<GfxMode> &modes);
/// mac specific stuff while calling CDriverGL::getWindowSize() /// mac specific stuff while calling CDriverGL::getWindowSize()
void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height); void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height);

View file

@ -386,6 +386,81 @@ void getCurrentScreenMode(nlWindow wnd, GfxMode& mode)
} }
} }
/// helper to extract bits per pixel value from screen mode, only 16 or 32 bits
static int bppFromDisplayMode(CGDisplayModeRef mode)
{
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
if(CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 32;
else if(CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels),
kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 16;
return 0;
}
/// get the list of available screen modes
bool getModes(std::vector<GfxMode> &modes)
{
static const CGDisplayCount kMaxDisplays = 16;
CGDirectDisplayID display[kMaxDisplays];
CGDisplayCount numDisplays;
CGDisplayErr err = CGGetActiveDisplayList(kMaxDisplays, display, &numDisplays);
if(err != CGDisplayNoErr)
{
nlwarning("Cannot get displays (%d)", err);
return false;
}
nldebug("3D: %d displays found", (int)numDisplays);
for (CGDisplayCount i = 0; i < numDisplays; ++i)
{
CGDirectDisplayID dspy = display[i];
CFArrayRef modeList = CGDisplayCopyAllDisplayModes(dspy, NULL);
if (modeList == NULL)
{
nlwarning("Display is invalid");
continue;
}
for (CFIndex j = 0; j < CFArrayGetCount(modeList); ++j)
{
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modeList, j);
uint8 bpp = bppFromDisplayMode(mode);
if (bpp >= 16)
{
uint16 w = CGDisplayModeGetWidth(mode);
uint16 h = CGDisplayModeGetHeight(mode);
// Add this mode
GfxMode mode;
mode.Width = w;
mode.Height = h;
mode.Depth = bpp;
// Frequency stays at 0 because on mac cocoa, display resolution
// is never really changed. if rendering res < display res,
// cocoa interpolates and keeps the display at it's original res.
// In case of x11 on mac, fullscreen is not supported, so again, no
// mode switching is done.
mode.Frequency = 0;
modes.push_back (mode);
nldebug(" Display 0x%x: Mode %dx%d, %d BPP", dspy, w, h, bpp);
}
}
}
return true;
}
/// get the size of the window's content area /// get the size of the window's content area
void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height) void getWindowSize(nlWindow wnd, uint32 &width, uint32 &height)
{ {