mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
parent
f82a940878
commit
ef7f856c46
12
panda/src/cocoadisplay/cocoaGraphicsBuffer.I
Normal file
12
panda/src/cocoadisplay/cocoaGraphicsBuffer.I
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file cocoaGraphicsBuffer.I
|
||||
* @author rdb
|
||||
* @date 2017-12-19
|
||||
*/
|
61
panda/src/cocoadisplay/cocoaGraphicsBuffer.h
Normal file
61
panda/src/cocoadisplay/cocoaGraphicsBuffer.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file cocoaGraphicsBuffer.h
|
||||
* @author rdb
|
||||
* @date 2017-12-19
|
||||
*/
|
||||
|
||||
#ifndef COCOAGRAPHICSBUFFER_H
|
||||
#define COCOAGRAPHICSBUFFER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "glgsg.h"
|
||||
|
||||
/**
|
||||
* This is a light wrapper around GLGraphicsBuffer (ie. FBOs) to interface
|
||||
* with Cocoa contexts, so that it can be used without a host window.
|
||||
*/
|
||||
class CocoaGraphicsBuffer : public GLGraphicsBuffer {
|
||||
public:
|
||||
CocoaGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host);
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
protected:
|
||||
virtual void close_buffer();
|
||||
virtual bool open_buffer();
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
GLGraphicsBuffer::init_type();
|
||||
register_type(_type_handle, "CocoaGraphicsBuffer",
|
||||
GLGraphicsBuffer::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "cocoaGraphicsBuffer.I"
|
||||
|
||||
#endif
|
165
panda/src/cocoadisplay/cocoaGraphicsBuffer.mm
Normal file
165
panda/src/cocoadisplay/cocoaGraphicsBuffer.mm
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file cocoaGraphicsBuffer.mm
|
||||
* @author rdb
|
||||
* @date 2017-12-19
|
||||
*/
|
||||
|
||||
#include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
TypeHandle CocoaGraphicsBuffer::_type_handle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CocoaGraphicsBuffer::
|
||||
CocoaGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) : // Ignore the host.
|
||||
GLGraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread before beginning
|
||||
* rendering for a given frame. It should do whatever setup is required, and
|
||||
* return true if the frame should be rendered, or false if it should be
|
||||
* skipped.
|
||||
*/
|
||||
bool CocoaGraphicsBuffer::
|
||||
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (_gsg == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
DCAST_INTO_R(cocoagsg, _gsg, false);
|
||||
nassertr(cocoagsg->_context != nil, false);
|
||||
|
||||
// Lock the context and make it current.
|
||||
{
|
||||
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||
cocoagsg->lock_context();
|
||||
[cocoagsg->_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return GLGraphicsBuffer::begin_frame(mode, current_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after rendering is
|
||||
* completed for a given frame. It should do whatever finalization is
|
||||
* required.
|
||||
*/
|
||||
void CocoaGraphicsBuffer::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
nassertv(_gsg != nullptr);
|
||||
|
||||
GLGraphicsBuffer::end_frame(mode, current_thread);
|
||||
|
||||
// Release the context.
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
DCAST_INTO_V(cocoagsg, _gsg);
|
||||
cocoagsg->unlock_context();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the buffer right now. Called from the window thread. Returns true
|
||||
* if the buffer is successfully opened, or false if there was a problem.
|
||||
*/
|
||||
bool CocoaGraphicsBuffer::
|
||||
open_buffer() {
|
||||
CocoaGraphicsPipe *cocoa_pipe;
|
||||
DCAST_INTO_R(cocoa_pipe, _pipe, false);
|
||||
|
||||
// GSG CreationInitialization
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
if (_gsg == nullptr) {
|
||||
// There is no old gsg. Create a new one.
|
||||
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, nullptr);
|
||||
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
|
||||
_gsg = cocoagsg;
|
||||
} else {
|
||||
// If the old gsg has the wrong pixel format, create a new one that shares
|
||||
// with the old gsg.
|
||||
DCAST_INTO_R(cocoagsg, _gsg, false);
|
||||
if (!cocoagsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||
cocoagsg = new CocoaGraphicsStateGuardian(_engine, _pipe, cocoagsg);
|
||||
cocoagsg->choose_pixel_format(_fb_properties, cocoa_pipe->get_display_id(), false);
|
||||
_gsg = cocoagsg;
|
||||
}
|
||||
}
|
||||
|
||||
FrameBufferProperties desired_props(_fb_properties);
|
||||
|
||||
// Lock the context, so we can safely operate on it.
|
||||
cocoagsg->lock_context();
|
||||
|
||||
// Make the context current and initialize what we need.
|
||||
[cocoagsg->_context makeCurrentContext];
|
||||
[cocoagsg->_context update];
|
||||
cocoagsg->reset_if_new();
|
||||
|
||||
// These properties are determined by choose_pixel_format.
|
||||
_fb_properties.set_force_hardware(cocoagsg->_fbprops.get_force_hardware());
|
||||
_fb_properties.set_force_software(cocoagsg->_fbprops.get_force_software());
|
||||
|
||||
bool success = GLGraphicsBuffer::open_buffer();
|
||||
if (success) {
|
||||
rebuild_bitplanes();
|
||||
if (_needs_rebuild) {
|
||||
// If it still needs rebuild, then something must have gone wrong.
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (success && !_fb_properties.verify_hardware_software
|
||||
(desired_props, cocoagsg->get_gl_renderer())) {
|
||||
GLGraphicsBuffer::close_buffer();
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Release the context.
|
||||
cocoagsg->unlock_context();
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the buffer right now. Called from the window thread.
|
||||
*/
|
||||
void CocoaGraphicsBuffer::
|
||||
close_buffer() {
|
||||
if (_gsg != nullptr) {
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
|
||||
|
||||
if (cocoagsg != nullptr && cocoagsg->_context != nil) {
|
||||
cocoagsg->lock_context();
|
||||
GLGraphicsBuffer::close_buffer();
|
||||
cocoagsg->unlock_context();
|
||||
}
|
||||
_gsg.clear();
|
||||
} else {
|
||||
GLGraphicsBuffer::close_buffer();
|
||||
}
|
||||
}
|
@ -18,11 +18,3 @@ INLINE CGDirectDisplayID CocoaGraphicsPipe::
|
||||
get_display_id() const {
|
||||
return _display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Cocoa NSScreen pointer associated with this graphics pipe.
|
||||
*/
|
||||
INLINE NSScreen *CocoaGraphicsPipe::
|
||||
get_nsscreen() const {
|
||||
return _screen;
|
||||
}
|
||||
|
@ -35,13 +35,10 @@ class FrameBufferProperties;
|
||||
*/
|
||||
class CocoaGraphicsPipe : public GraphicsPipe {
|
||||
public:
|
||||
CocoaGraphicsPipe();
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display);
|
||||
CocoaGraphicsPipe(NSScreen *screen);
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display = CGMainDisplayID());
|
||||
virtual ~CocoaGraphicsPipe();
|
||||
|
||||
INLINE CGDirectDisplayID get_display_id() const;
|
||||
INLINE NSScreen *get_nsscreen() const;
|
||||
|
||||
virtual string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
@ -64,11 +61,8 @@ protected:
|
||||
private:
|
||||
void load_display_information();
|
||||
|
||||
// _display and _screen refer to the same thing, NSScreen being the tiny
|
||||
// Cocoa wrapper around the Quartz display ID. NSScreen isn't generally
|
||||
// useful, but we need it when creating the window.
|
||||
// This is the Quartz display identifier.
|
||||
CGDirectDisplayID _display;
|
||||
NSScreen *_screen;
|
||||
|
||||
friend class CocoaGraphicsWindow;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
// #include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "cocoaPandaApp.h"
|
||||
@ -30,104 +30,32 @@
|
||||
|
||||
TypeHandle CocoaGraphicsPipe::_type_handle;
|
||||
|
||||
static void init_app() {
|
||||
if (NSApp == nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[CocoaPandaApp sharedApplication];
|
||||
/**
|
||||
* Takes a CoreGraphics display ID, which defaults to the main display.
|
||||
*/
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display) : _display(display) {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
#endif
|
||||
[NSApp finishLaunching];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Put Cocoa into thread-safe mode by spawning a thread which immediately
|
||||
// exits.
|
||||
NSThread* thread = [[NSThread alloc] init];
|
||||
[thread start];
|
||||
[thread autorelease];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the main screen (the one the user is most likely to be working in at
|
||||
* the moment).
|
||||
*/
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe() {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
|
||||
init_app();
|
||||
|
||||
_screen = [NSScreen mainScreen];
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num longValue];
|
||||
// We used to also obtain the corresponding NSScreen here, but this causes
|
||||
// the application icon to start bouncing, which may be undesirable for
|
||||
// apps that will never open a window.
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for main screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a CoreGraphics display ID.
|
||||
*/
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe(CGDirectDisplayID display) {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
_display = display;
|
||||
|
||||
init_app();
|
||||
|
||||
// Iterate over the screens to find the one with our display ID.
|
||||
NSEnumerator *e = [[NSScreen screens] objectEnumerator];
|
||||
while (NSScreen *screen = (NSScreen *) [e nextObject]) {
|
||||
NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
if (display == (CGDirectDisplayID) [num longValue]) {
|
||||
_screen = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an NSScreen pointer.
|
||||
*/
|
||||
CocoaGraphicsPipe::
|
||||
CocoaGraphicsPipe(NSScreen *screen) {
|
||||
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
|
||||
_is_valid = true;
|
||||
|
||||
init_app();
|
||||
|
||||
if (screen == nil) {
|
||||
_screen = [NSScreen mainScreen];
|
||||
} else {
|
||||
_screen = screen;
|
||||
}
|
||||
NSNumber *num = [[_screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
_display = (CGDirectDisplayID) [num longValue];
|
||||
|
||||
_display_width = CGDisplayPixelsWide(_display);
|
||||
_display_height = CGDisplayPixelsHigh(_display);
|
||||
load_display_information();
|
||||
|
||||
cocoadisplay_cat.debug()
|
||||
<< "Creating CocoaGraphicsPipe for screen "
|
||||
<< _screen << " with display ID " << _display << "\n";
|
||||
<< "Creating CocoaGraphicsPipe for display ID " << _display << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,10 +236,12 @@ make_output(const string &name,
|
||||
flags, gsg, host);
|
||||
}
|
||||
|
||||
// Second thing to try: a GLGraphicsBuffer
|
||||
// Second thing to try: a GLGraphicsBuffer. This requires a context, so if
|
||||
// we don't have a host window, we instead create a CocoaGraphicsBuffer,
|
||||
// which wraps around GLGraphicsBuffer and manages a context.
|
||||
|
||||
if (retry == 1) {
|
||||
if (!gl_support_fbo || host == NULL ||
|
||||
if (!gl_support_fbo ||
|
||||
(flags & (BF_require_parasite | BF_require_window)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -334,33 +264,14 @@ make_output(const string &name,
|
||||
precertify = true;
|
||||
}
|
||||
}
|
||||
if (host != NULL) {
|
||||
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
/*
|
||||
// Third thing to try: a CocoaGraphicsBuffer
|
||||
if (retry == 2) {
|
||||
if (((flags&BF_require_parasite)!=0)||
|
||||
((flags&BF_require_window)!=0)||
|
||||
((flags&BF_resizeable)!=0)||
|
||||
((flags&BF_size_track_host)!=0)||
|
||||
((flags&BF_can_bind_layered)!=0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!support_rtt) {
|
||||
if (((flags&BF_rtt_cumulative)!=0)||
|
||||
((flags&BF_can_bind_every)!=0)) {
|
||||
// If we require Render-to-Texture, but can't be sure we support it,
|
||||
// bail.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return new CocoaGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Nothing else left to try.
|
||||
return NULL;
|
||||
|
@ -19,3 +19,21 @@ INLINE const FrameBufferProperties &CocoaGraphicsStateGuardian::
|
||||
get_fb_properties() const {
|
||||
return _fbprops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the context.
|
||||
*/
|
||||
INLINE void CocoaGraphicsStateGuardian::
|
||||
lock_context() {
|
||||
nassertv(_context != nil);
|
||||
CGLLockContext((CGLContextObj) [_context CGLContextObj]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the context.
|
||||
*/
|
||||
INLINE void CocoaGraphicsStateGuardian::
|
||||
unlock_context() {
|
||||
nassertv(_context != nil);
|
||||
CGLUnlockContext((CGLContextObj) [_context CGLContextObj]);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "glgsg.h"
|
||||
|
||||
#import <AppKit/NSOpenGL.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
/**
|
||||
* A tiny specialization on GLGraphicsStateGuardian to add some Cocoa-specific
|
||||
@ -38,6 +39,9 @@ public:
|
||||
|
||||
virtual ~CocoaGraphicsStateGuardian();
|
||||
|
||||
INLINE void lock_context();
|
||||
INLINE void unlock_context();
|
||||
|
||||
NSOpenGLContext *_share_context;
|
||||
NSOpenGLContext *_context;
|
||||
FrameBufferProperties _fbprops;
|
||||
|
@ -65,6 +65,16 @@ CocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
_fullscreen_mode = NULL;
|
||||
_windowed_mode = NULL;
|
||||
|
||||
// Now that we know for sure we want a window, we can create the Cocoa app.
|
||||
// This will cause the application icon to appear and start bouncing.
|
||||
if (NSApp == nil) {
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
#endif
|
||||
[NSApp finishLaunching];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
|
||||
add_input_device(device);
|
||||
@ -144,7 +154,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
nassertr(_view != nil, false);
|
||||
|
||||
// Place a lock on the context.
|
||||
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->lock_context();
|
||||
|
||||
// Set the drawable.
|
||||
if (_properties.get_fullscreen()) {
|
||||
@ -210,7 +220,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
DCAST_INTO_V(cocoagsg, _gsg);
|
||||
|
||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->unlock_context();
|
||||
|
||||
if (mode == FM_render) {
|
||||
// end_render_texture();
|
||||
@ -239,7 +249,7 @@ end_flip() {
|
||||
CocoaGraphicsStateGuardian *cocoagsg;
|
||||
DCAST_INTO_V(cocoagsg, _gsg);
|
||||
|
||||
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->lock_context();
|
||||
|
||||
// Swap the front and back buffer.
|
||||
[cocoagsg->_context flushBuffer];
|
||||
@ -247,7 +257,7 @@ end_flip() {
|
||||
// Flush the window
|
||||
[[_view window] flushWindow];
|
||||
|
||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->unlock_context();
|
||||
}
|
||||
GraphicsWindow::end_flip();
|
||||
}
|
||||
@ -399,6 +409,16 @@ open_window() {
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over the screens to find the one with our display ID.
|
||||
NSScreen *screen;
|
||||
NSEnumerator *e = [[NSScreen screens] objectEnumerator];
|
||||
while (screen = (NSScreen *) [e nextObject]) {
|
||||
NSNumber *num = [[screen deviceDescription] objectForKey: @"NSScreenNumber"];
|
||||
if (cocoa_pipe->_display == (CGDirectDisplayID) [num longValue]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Center the window if coordinates were set to -1 or -2 TODO: perhaps in
|
||||
// future, in the case of -1, it should use the origin used in a previous
|
||||
// run of Panda
|
||||
@ -406,7 +426,7 @@ open_window() {
|
||||
if (parent_nsview != NULL) {
|
||||
container = [parent_nsview bounds];
|
||||
} else {
|
||||
container = [cocoa_pipe->_screen frame];
|
||||
container = [screen frame];
|
||||
container.origin = NSMakePoint(0, 0);
|
||||
}
|
||||
int x = _properties.get_x_origin();
|
||||
@ -453,7 +473,7 @@ open_window() {
|
||||
_window = [[CocoaPandaWindow alloc]
|
||||
initWithContentRect: rect
|
||||
styleMask:windowStyle
|
||||
screen:cocoa_pipe->_screen
|
||||
screen:screen
|
||||
window:this];
|
||||
|
||||
if (_window == nil) {
|
||||
@ -464,7 +484,7 @@ open_window() {
|
||||
}
|
||||
|
||||
// Lock the context, so we can safely operate on it.
|
||||
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->lock_context();
|
||||
|
||||
// Create the NSView to render to.
|
||||
NSRect rect = NSMakeRect(0, 0, _properties.get_x_size(), _properties.get_y_size());
|
||||
@ -588,7 +608,7 @@ open_window() {
|
||||
cocoagsg->reset_if_new();
|
||||
|
||||
// Release the context.
|
||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->unlock_context();
|
||||
|
||||
if (!cocoagsg->is_valid()) {
|
||||
close_window();
|
||||
@ -637,9 +657,9 @@ close_window() {
|
||||
cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
|
||||
|
||||
if (cocoagsg != NULL && cocoagsg->_context != nil) {
|
||||
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->lock_context();
|
||||
[cocoagsg->_context clearDrawable];
|
||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->unlock_context();
|
||||
}
|
||||
_gsg.clear();
|
||||
}
|
||||
@ -1429,9 +1449,9 @@ handle_close_event() {
|
||||
cocoagsg = DCAST(CocoaGraphicsStateGuardian, _gsg);
|
||||
|
||||
if (cocoagsg != NULL && cocoagsg->_context != nil) {
|
||||
CGLLockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->lock_context();
|
||||
[cocoagsg->_context clearDrawable];
|
||||
CGLUnlockContext((CGLContextObj) [cocoagsg->_context CGLContextObj]);
|
||||
cocoagsg->unlock_context();
|
||||
}
|
||||
_gsg.clear();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
@ -40,6 +41,7 @@ init_libcocoadisplay() {
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
CocoaGraphicsBuffer::init_type();
|
||||
CocoaGraphicsPipe::init_type();
|
||||
CocoaGraphicsStateGuardian::init_type();
|
||||
CocoaGraphicsWindow::init_type();
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "config_cocoadisplay.mm"
|
||||
#include "cocoaGraphicsBuffer.mm"
|
||||
#include "cocoaGraphicsPipe.mm"
|
||||
#include "cocoaGraphicsStateGuardian.mm"
|
||||
#include "cocoaGraphicsWindow.mm"
|
||||
|
@ -213,6 +213,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_host != nullptr) {
|
||||
if (!_host->begin_frame(FM_parasite, current_thread)) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
@ -220,6 +221,13 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// We don't have a host window, which is possible for CocoaGraphicsBuffer.
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
if (!_gsg->begin_frame(current_thread)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out the desired size of the buffer.
|
||||
if (mode == FM_render) {
|
||||
@ -235,7 +243,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
}
|
||||
}
|
||||
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
|
||||
if (_host->get_size() != _size) {
|
||||
if (_host != nullptr && _host->get_size() != _size) {
|
||||
// We also need to rebuild if we need to change size.
|
||||
_needs_rebuild = true;
|
||||
}
|
||||
@ -356,7 +364,7 @@ rebuild_bitplanes() {
|
||||
|
||||
// Calculate bitplane size. This can be larger than the buffer.
|
||||
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
|
||||
if (_host->get_size() != _size) {
|
||||
if (_host != nullptr && _host->get_size() != _size) {
|
||||
set_size_and_recalc(_host->get_x_size(),
|
||||
_host->get_y_size());
|
||||
}
|
||||
@ -1253,7 +1261,11 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
generate_mipmaps();
|
||||
}
|
||||
|
||||
if (_host != nullptr) {
|
||||
_host->end_frame(FM_parasite, current_thread);
|
||||
} else {
|
||||
glgsg->end_frame(current_thread);
|
||||
}
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
@ -1315,8 +1327,11 @@ bool CLP(GraphicsBuffer)::
|
||||
open_buffer() {
|
||||
report_my_gl_errors();
|
||||
|
||||
// Double check that we have a host
|
||||
nassertr(_host != 0, false);
|
||||
// Double check that we have a valid gsg
|
||||
nassertr(_gsg != nullptr, false);
|
||||
if (!_gsg->is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Count total color buffers.
|
||||
int totalcolor =
|
||||
@ -1491,8 +1506,10 @@ open_buffer() {
|
||||
_fb_properties.set_back_buffers(0);
|
||||
_fb_properties.set_indexed_color(0);
|
||||
_fb_properties.set_rgb_color(1);
|
||||
if (_host != nullptr) {
|
||||
_fb_properties.set_force_hardware(_host->get_fb_properties().get_force_hardware());
|
||||
_fb_properties.set_force_software(_host->get_fb_properties().get_force_software());
|
||||
}
|
||||
|
||||
_is_valid = true;
|
||||
_needs_rebuild = true;
|
||||
@ -1508,7 +1525,7 @@ open_buffer() {
|
||||
*/
|
||||
GraphicsOutput *CLP(GraphicsBuffer)::
|
||||
get_host() {
|
||||
return _host;
|
||||
return (_host != nullptr) ? _host : this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1699,7 +1716,7 @@ report_my_errors(int line, const char *file) {
|
||||
*/
|
||||
void CLP(GraphicsBuffer)::
|
||||
check_host_valid() {
|
||||
if ((_host == 0)||(!_host->is_valid())) {
|
||||
if (_host != nullptr && !_host->is_valid()) {
|
||||
_rb_data_size_bytes = 0;
|
||||
if (_rb_context != NULL) {
|
||||
// We must delete this object first, because when the GSG destructs, so
|
||||
|
@ -86,8 +86,6 @@ protected:
|
||||
|
||||
void report_my_errors(int line, const char *file);
|
||||
|
||||
private:
|
||||
|
||||
void bind_slot(int layer, bool rb_resize, Texture **attach,
|
||||
RenderTexturePlane plane, GLenum attachpoint);
|
||||
void bind_slot_multisample(bool rb_resize, Texture **attach,
|
||||
|
Loading…
x
Reference in New Issue
Block a user