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,
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)) {
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
bool is_basic() const
Returns true if the properties are extremely basic.
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
An object to create GraphicsOutputs that share a particular 3-D API.
Encapsulates all the communication with a particular instance of a given rendering backend.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
float get_blue(int x, int y) const
Returns the blue component color at the indicated pixel.
float get_alpha(int x, int y) const
Returns the alpha component color at the indicated pixel.
float get_gray(int x, int y) const
Returns the gray component color at the indicated pixel.
float get_green(int x, int y) const
Returns the green component color at the indicated pixel.
float get_red(int x, int y) const
Returns the red component color at the indicated pixel.
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This object represents a window on the desktop, not necessarily a Panda window.
get_os_handle
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
get_parent_window
Returns the parent window specification, or NULL if there is no parent window specified.
An offscreen buffer in the OSX environment.
This graphics pipe represents the interface for creating OpenGL graphics windows on the various OSX's...
virtual PreferredWindowThread get_preferred_window_thread() const
Returns an indication of the thread in which this GraphicsPipe requires its window processing to be p...
static CGImageRef create_cg_image(const PNMImage &pnm_image)
Creates a new Quartz bitmap image with the data in the indicated PNMImage.
virtual std::string get_interface_name() const
Returns the name of the rendering interface associated with this GraphicsPipe.
A tiny specialization on GLGraphicsStateGuardian to add some wgl-specific information.
An interface to the osx/ system for managing GL windows under X.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(GraphicsPipe) osxGraphicsPipe
This function is passed to the GraphicsPipeSelection object to allow the user to make a default osxGr...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.