21 #import <Carbon/Carbon.h> 24 #define GetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth) 25 #define GetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight) 26 #define GetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate) 27 #define GetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel) 28 #define GetModeSafeForHardware(mode) GetDictionaryBoolean((mode), kCGDisplayModeIsSafeForHardware) 29 #define GetModeStretched(mode) GetDictionaryBoolean((mode), kCGDisplayModeIsStretched) 30 #define MAX_DISPLAYS 32 32 Boolean GetDictionaryBoolean(CFDictionaryRef theDict,
const void* key) {
34 Boolean value =
false;
36 boolRef = (CFBooleanRef)CFDictionaryGetValue(theDict, key);
37 if (boolRef !=
nullptr)
38 value = CFBooleanGetValue(boolRef);
42 long GetDictionaryLong(CFDictionaryRef theDict,
const void* key) {
46 numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
47 if (numRef !=
nullptr)
48 CFNumberGetValue(numRef, kCFNumberLongType, &value);
52 static CFComparisonResult CompareModes (
const void *val1,
const void *val2,
void *context) {
54 #pragma unused(context) 55 CFDictionaryRef thisMode = (CFDictionaryRef)val1;
56 CFDictionaryRef otherMode = (CFDictionaryRef)val2;
58 long width = GetModeWidth(thisMode);
59 long otherWidth = GetModeWidth(otherMode);
60 long height = GetModeHeight(thisMode);
61 long otherHeight = GetModeHeight(otherMode);
64 if (width * height < otherWidth * otherHeight) {
65 return kCFCompareLessThan;
66 }
else if (width * height > otherWidth * otherHeight) {
67 return kCFCompareGreaterThan;
71 long bitsPerPixel = GetModeBitsPerPixel(thisMode);
72 long otherBitsPerPixel = GetModeBitsPerPixel(otherMode);
73 if (bitsPerPixel < otherBitsPerPixel) {
74 return kCFCompareLessThan;
75 }
else if (bitsPerPixel > otherBitsPerPixel) {
76 return kCFCompareGreaterThan;
80 long refreshRate = GetModeRefreshRate(thisMode);
81 long otherRefreshRate = GetModeRefreshRate(otherMode);
82 if (refreshRate < otherRefreshRate) {
83 return kCFCompareLessThan;
84 }
else if (refreshRate > otherRefreshRate) {
85 return kCFCompareGreaterThan;
88 return kCFCompareEqualTo;
91 CFArrayRef GSCGDisplayAvailableModesUsefulForOpenGL(CGDirectDisplayID display) {
93 CFArrayRef availableModes = CGDisplayAvailableModes(display);
94 unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes);
97 CFMutableArrayRef usefulModes = CFArrayCreateMutable(kCFAllocatorDefault, numberOfAvailableModes,
nullptr);
100 long currentModeBitsPerPixel = GetModeBitsPerPixel(CGDisplayCurrentMode(display));
103 for (i= 0; i<numberOfAvailableModes; ++i) {
105 CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, i);
110 long bitsPerPixel = GetModeBitsPerPixel(mode);
111 Boolean safeForHardware = GetModeSafeForHardware(mode);
112 Boolean stretched = GetModeStretched(mode);
114 if ((bitsPerPixel != currentModeBitsPerPixel) || (!safeForHardware) || (stretched)) {
118 long width = GetModeWidth(mode);
119 long height = GetModeHeight(mode);
120 long refreshRate = GetModeRefreshRate(mode);
121 Boolean replaced =
false;
122 Boolean skipped =
false;
127 unsigned int currentNumberOfUsefulModes = CFArrayGetCount(usefulModes);
128 for (j = 0; j < currentNumberOfUsefulModes; ++j) {
129 CFDictionaryRef otherMode = (CFDictionaryRef)CFArrayGetValueAtIndex(usefulModes, j);
130 long otherWidth = GetModeWidth(otherMode);
131 long otherHeight = GetModeHeight(otherMode);
132 if ((otherWidth == width) && (otherHeight == height)) {
133 long otherRefreshRate = GetModeRefreshRate(otherMode);
134 if (otherRefreshRate < refreshRate) {
136 const void* value = mode;
137 CFArrayReplaceValues(usefulModes, CFRangeMake(j ,1), &value, 1);
141 else if (otherRefreshRate > refreshRate) {
148 if (!replaced && !skipped) {
149 CFArrayAppendValue(usefulModes, mode);
153 CFArraySortValues( usefulModes,
154 CFRangeMake(0, CFArrayGetCount(usefulModes)),
155 (CFComparatorFunction) CompareModes,
nullptr);
167 CGRect display_bounds = CGDisplayBounds(kCGDirectMainDisplay);
168 _display_width = CGRectGetWidth(display_bounds);
169 _display_height = CGRectGetHeight(display_bounds);
171 CGDirectDisplayID display, displayArray[MAX_DISPLAYS] ;
172 CGDisplayCount numDisplays;
173 CFDictionaryRef displayMode;
174 CFArrayRef displayModeArray;
176 CGGetActiveDisplayList (MAX_DISPLAYS, displayArray, &numDisplays);
177 display = displayArray [numDisplays - 1];
178 displayModeArray = GSCGDisplayAvailableModesUsefulForOpenGL( display );
179 number = CFArrayGetCount( displayModeArray );
181 for(i = 0; i < number; i++) {
182 displayMode = (CFDictionaryRef) CFArrayGetValueAtIndex (displayModeArray, i);
183 _display_information -> _total_display_modes++;
184 displays[i].width = (
signed int)GetModeWidth (displayMode);
185 displays[i].height = (
signed int)GetModeHeight (displayMode);
186 displays[i].bits_per_pixel = (
signed int)GetModeBitsPerPixel (displayMode);
187 displays[i].refresh_rate = (
signed int)GetModeRefreshRate (displayMode);
189 _display_information -> _display_mode_array = displays;
224 GraphicsPipe::PreferredWindowThread
239 size_t bytes_per_component = 2;
241 size_t bytes_per_component = 1;
243 size_t bits_per_component = bytes_per_component * 8;
246 size_t bits_per_pixel = num_components * bits_per_component;
247 size_t bytes_per_row = num_components * bytes_per_component * width;
249 size_t num_bytes = bytes_per_row * height;
253 CFStringRef color_space_name =
nullptr;
255 case PNMImage::CT_grayscale:
256 color_space_name = kCGColorSpaceGenericGray;
261 case PNMImage::CT_two_channel:
262 color_space_name = kCGColorSpaceGenericGray;
267 case PNMImage::CT_color:
268 color_space_name = kCGColorSpaceGenericRGB;
270 is_grayscale =
false;
273 case PNMImage::CT_four_channel:
274 color_space_name = kCGColorSpaceGenericRGB;
276 is_grayscale =
false;
279 case PNMImage::CT_invalid:
281 nassertr(
false,
nullptr);
284 nassertr(color_space_name !=
nullptr,
nullptr);
286 CGColorSpaceRef color_space = CGColorSpaceCreateWithName(color_space_name);
287 nassertr(color_space !=
nullptr,
nullptr);
289 CGBitmapInfo bitmap_info = 0;
291 bitmap_info |= kCGBitmapByteOrder16Host;
294 bitmap_info |= kCGImageAlphaLast;
298 char *char_array = (
char *)PANDA_MALLOC_ARRAY(num_bytes);
300 xelval *dp = (xelval *)char_array;
301 for (
size_t yi = 0; yi < height; ++yi) {
302 for (
size_t xi = 0; xi < width; ++xi) {
304 *dp++ = (xelval)(pnm_image.
get_gray(xi, yi) * PGM_MAXMAXVAL);
306 *dp++ = (xelval)(pnm_image.
get_red(xi, yi) * PGM_MAXMAXVAL);
307 *dp++ = (xelval)(pnm_image.
get_green(xi, yi) * PGM_MAXMAXVAL);
308 *dp++ = (xelval)(pnm_image.
get_blue(xi, yi) * PGM_MAXMAXVAL);
311 *dp++ = (xelval)(pnm_image.
get_alpha(xi, yi) * PGM_MAXMAXVAL);
315 nassertr((
void *)dp == (
void *)(char_array + num_bytes),
nullptr);
317 CGDataProviderRef provider =
318 CGDataProviderCreateWithData(
nullptr, char_array, num_bytes, release_data);
319 nassertr(provider !=
nullptr,
nullptr);
321 CGImageRef image = CGImageCreate
322 (width, height, bits_per_component, bits_per_pixel, bytes_per_row,
323 color_space, bitmap_info, provider,
324 nullptr,
false, kCGRenderingIntentDefault);
325 nassertr(image !=
nullptr,
nullptr);
327 CGColorSpaceRelease(color_space);
328 CGDataProviderRelease(provider);
337 void osxGraphicsPipe::
338 release_data(
void *info,
const void *data,
size_t size) {
339 char *char_array = (
char *)data;
340 PANDA_FREE_ARRAY(char_array);
347 make_output(
const std::string &name,
362 DCAST_INTO_R(osxgsg, gsg,
nullptr);
368 if (((flags&BF_require_parasite)!=0)||
369 ((flags&BF_refuse_window)!=0)||
370 ((flags&BF_resizeable)!=0)||
371 ((flags&BF_size_track_host)!=0)||
372 ((flags&BF_can_bind_color)!=0)||
373 ((flags&BF_can_bind_every)!=0)||
374 ((flags&BF_can_bind_layered)!=0)) {
378 if (window_handle !=
nullptr) {
379 osxdisplay_cat.info()
380 <<
"Got parent_window " << *window_handle <<
"\n";
381 #ifdef SUPPORT_SUBPROCESS_WINDOW 383 if (os_handle !=
nullptr &&
384 os_handle->
is_of_type(NativeWindowHandle::SubprocessHandle::get_class_type())) {
385 return new SubprocessWindow(engine,
this, name, fb_prop, win_prop,
388 #endif // SUPPORT_SUBPROCESS_WINDOW 397 if (!osx_support_gl_buffer || !gl_support_fbo || host ==
nullptr ||
398 (flags & (BF_require_parasite | BF_require_window)) != 0) {
403 if ((flags & BF_fb_props_optional) == 0) {
404 if (fb_prop.get_indexed_color() ||
405 fb_prop.get_back_buffers() > 0 ||
406 fb_prop.get_accum_bits() > 0) {
410 if (osxgsg !=
nullptr && osxgsg->is_valid() && !osxgsg->needs_reset()) {
411 if (!osxgsg->_supports_framebuffer_object ||
412 osxgsg->_glDrawBuffers ==
nullptr) {
420 return new GLGraphicsBuffer(engine,
this, name, fb_prop, win_prop, flags, gsg, host);
425 if ((!support_render_texture)||
426 ((flags&BF_require_parasite)!=0)||
427 ((flags&BF_require_window)!=0)||
428 ((flags&BF_resizeable)!=0)||
429 ((flags&BF_size_track_host)!=0)||
430 ((flags&BF_can_bind_every)!=0)||
431 ((flags&BF_can_bind_layered)!=0)) {
bool is_basic() const
Returns true if the properties are extremely basic.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object represents a window on the desktop, not necessarily a Panda window.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An offscreen buffer in the OSX environment.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_parent_window
Returns the parent window specification, or NULL if there is no parent window specified.
static CGImageRef create_cg_image(const PNMImage &pnm_image)
Creates a new Quartz bitmap image with the data in the indicated PNMImage.
This graphics pipe represents the interface for creating OpenGL graphics windows on the various OSX's...
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
float get_blue(int x, int y) const
Returns the blue component color at the indicated pixel.
PT(GraphicsPipe) osxGraphicsPipe
This function is passed to the GraphicsPipeSelection object to allow the user to make a default osxGr...
A tiny specialization on GLGraphicsStateGuardian to add some wgl-specific information.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_os_handle
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
float get_red(int x, int y) const
Returns the red component color at the indicated pixel.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
float get_green(int x, int y) const
Returns the green component color at the indicated pixel.
An interface to the osx/ system for managing GL windows under X.
An object to create GraphicsOutputs that share a particular 3-D API.
virtual std::string get_interface_name() const
Returns the name of the rendering interface associated with this GraphicsPipe.
This is a base class for the various different classes that represent the result of a frame of render...
Encapsulates all the communication with a particular instance of a given rendering backend.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This class is the main interface to controlling the render process.
TypeHandle is the identifier used to differentiate C++ class types.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual PreferredWindowThread get_preferred_window_thread() const
Returns an indication of the thread in which this GraphicsPipe requires its window processing to be p...
float get_alpha(int x, int y) const
Returns the alpha component color at the indicated pixel.