mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-27 15:25:54 -04:00
tinydisplay: Add Cocoa-based backend
Adds support for tinydisplay rendering on macOS Fixes #1285
This commit is contained in:
parent
545ede9d94
commit
a5fe1fa4bd
@ -5034,6 +5034,8 @@ if not PkgSkip("TINYDISPLAY"):
|
||||
OPTS=['DIR:panda/src/tinydisplay', 'BUILDING:TINYDISPLAY', 'X11']
|
||||
if not PkgSkip("X11"):
|
||||
OPTS += ['X11']
|
||||
if not PkgSkip("COCOA"):
|
||||
OPTS += ['COCOA']
|
||||
TargetAdd('p3tinydisplay_composite1.obj', opts=OPTS, input='p3tinydisplay_composite1.cxx')
|
||||
TargetAdd('p3tinydisplay_composite2.obj', opts=OPTS, input='p3tinydisplay_composite2.cxx')
|
||||
TargetAdd('p3tinydisplay_ztriangle_1.obj', opts=OPTS, input='ztriangle_1.cxx')
|
||||
@ -5044,7 +5046,13 @@ if not PkgSkip("TINYDISPLAY"):
|
||||
if GetTarget() == 'windows':
|
||||
TargetAdd('libp3tinydisplay.dll', input='libp3windisplay.dll')
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['WINIMM', 'WINGDI', 'WINKERNEL', 'WINOLDNAMES', 'WINUSER', 'WINMM'])
|
||||
elif GetTarget() != 'darwin' and not PkgSkip("X11"):
|
||||
elif GetTarget() == 'darwin':
|
||||
if not PkgSkip("COCOA"):
|
||||
TargetAdd('libp3tinydisplay_tinyCocoaGraphicsWindow.obj', opts=OPTS, input='tinyCocoaGraphicsWindow.mm')
|
||||
TargetAdd('libp3tinydisplay.dll', input='libp3tinydisplay_tinyCocoaGraphicsWindow.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3cocoadisplay_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['COCOA', 'CARBON', 'QUARTZ'])
|
||||
elif not PkgSkip("X11"):
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3x11display_composite1.obj')
|
||||
TargetAdd('libp3tinydisplay.dll', opts=['X11'])
|
||||
TargetAdd('libp3tinydisplay.dll', input='p3tinydisplay_composite1.obj')
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
|
||||
#include "config_tinydisplay.h"
|
||||
#include "tinyCocoaGraphicsPipe.h"
|
||||
#include "tinyCocoaGraphicsWindow.h"
|
||||
#include "tinyXGraphicsPipe.h"
|
||||
#include "tinyXGraphicsWindow.h"
|
||||
#include "tinyWinGraphicsPipe.h"
|
||||
@ -79,6 +81,14 @@ init_libtinydisplay() {
|
||||
|
||||
GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
TinyCocoaGraphicsPipe::init_type();
|
||||
TinyCocoaGraphicsWindow::init_type();
|
||||
selection->add_pipe_type(TinyCocoaGraphicsPipe::get_class_type(),
|
||||
TinyCocoaGraphicsPipe::pipe_constructor);
|
||||
ps->set_system_tag("TinyPanda", "native_window_system", "Cocoa");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_X11
|
||||
TinyXGraphicsPipe::init_type();
|
||||
TinyXGraphicsWindow::init_type();
|
||||
@ -116,6 +126,10 @@ init_libtinydisplay() {
|
||||
int
|
||||
get_pipe_type_p3tinydisplay() {
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
return TinyCocoaGraphicsPipe::get_class_type().get_index();
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
return TinyWinGraphicsPipe::get_class_type().get_index();
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "tinyCocoaGraphicsPipe.cxx"
|
||||
#include "tinyGraphicsStateGuardian.cxx"
|
||||
#include "tinyOffscreenGraphicsPipe.cxx"
|
||||
#include "tinySDLGraphicsPipe.cxx"
|
||||
|
12
panda/src/tinydisplay/tinyCocoaGraphicsPipe.I
Normal file
12
panda/src/tinydisplay/tinyCocoaGraphicsPipe.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 tinyCocoaGraphicsPipe.I
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
114
panda/src/tinydisplay/tinyCocoaGraphicsPipe.cxx
Normal file
114
panda/src/tinydisplay/tinyCocoaGraphicsPipe.cxx
Normal file
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* 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 tinyCocoaGraphicsPipe.cxx
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
|
||||
#include "tinyCocoaGraphicsPipe.h"
|
||||
#include "tinyCocoaGraphicsWindow.h"
|
||||
#include "tinyGraphicsStateGuardian.h"
|
||||
#include "tinyGraphicsBuffer.h"
|
||||
#include "config_tinydisplay.h"
|
||||
#include "frameBufferProperties.h"
|
||||
|
||||
TypeHandle TinyCocoaGraphicsPipe::_type_handle;
|
||||
|
||||
/**
|
||||
* Takes a CoreGraphics display ID, which defaults to the main display.
|
||||
*/
|
||||
TinyCocoaGraphicsPipe::
|
||||
TinyCocoaGraphicsPipe(CGDirectDisplayID display) : CocoaGraphicsPipe(display) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
TinyCocoaGraphicsPipe::
|
||||
~TinyCocoaGraphicsPipe() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the rendering interface associated with this
|
||||
* GraphicsPipe. This is used to present to the user to allow him/her to
|
||||
* choose between several possible GraphicsPipes available on a particular
|
||||
* platform, so the name should be meaningful and unique for a given platform.
|
||||
*/
|
||||
std::string TinyCocoaGraphicsPipe::
|
||||
get_interface_name() const {
|
||||
return "TinyPanda";
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is passed to the GraphicsPipeSelection object to allow the
|
||||
* user to make a default TinyCocoaGraphicsPipe.
|
||||
*/
|
||||
PT(GraphicsPipe) TinyCocoaGraphicsPipe::
|
||||
pipe_constructor() {
|
||||
return new TinyCocoaGraphicsPipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new window on the pipe, if possible.
|
||||
*/
|
||||
PT(GraphicsOutput) TinyCocoaGraphicsPipe::
|
||||
make_output(const std::string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsEngine *engine,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify) {
|
||||
TinyGraphicsStateGuardian *tinygsg = 0;
|
||||
if (gsg != 0) {
|
||||
DCAST_INTO_R(tinygsg, gsg, nullptr);
|
||||
}
|
||||
|
||||
// First thing to try: a TinyCocoaGraphicsWindow
|
||||
|
||||
// We check _is_valid only in this case. The pipe will be invalid if it
|
||||
// can't contact the X server, but that shouldn't prevent the creation of an
|
||||
// offscreen buffer.
|
||||
if (retry == 0 && _is_valid) {
|
||||
if ((flags & BF_require_parasite) != 0 ||
|
||||
(flags & BF_refuse_window) != 0 ||
|
||||
(flags & BF_resizeable) != 0 ||
|
||||
(flags & BF_size_track_host) != 0 ||
|
||||
(flags & BF_rtt_cumulative) != 0 ||
|
||||
(flags & BF_can_bind_color) != 0 ||
|
||||
(flags & BF_can_bind_every) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return new TinyCocoaGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host);
|
||||
}
|
||||
|
||||
// Second thing to try: a TinyGraphicsBuffer
|
||||
|
||||
// No need to check _is_valid here. We can create an offscreen buffer even
|
||||
// if the pipe is not technically valid.
|
||||
if (retry == 1) {
|
||||
if ((flags & BF_require_parasite) != 0 ||
|
||||
(flags & BF_require_window) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return new TinyGraphicsBuffer(engine, this, name, fb_prop, win_prop, flags, gsg, host);
|
||||
}
|
||||
|
||||
// Nothing else left to try.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // HAVE_COCOA
|
70
panda/src/tinydisplay/tinyCocoaGraphicsPipe.h
Normal file
70
panda/src/tinydisplay/tinyCocoaGraphicsPipe.h
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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 tinyCocoaGraphicsPipe.h
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
||||
|
||||
#ifndef TINYCOCOAGRAPHICSPIPE_H
|
||||
#define TINYCOCOAGRAPHICSPIPE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "cocoaGraphicsPipe.h"
|
||||
#include "tinyGraphicsStateGuardian.h"
|
||||
|
||||
/**
|
||||
* This graphics pipe represents the interface for creating TinyPanda graphics
|
||||
* windows on a Cocoa-based (macOS) client.
|
||||
*/
|
||||
class EXPCL_TINYDISPLAY TinyCocoaGraphicsPipe : public CocoaGraphicsPipe {
|
||||
public:
|
||||
TinyCocoaGraphicsPipe(CGDirectDisplayID display = CGMainDisplayID());
|
||||
virtual ~TinyCocoaGraphicsPipe();
|
||||
|
||||
virtual std::string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsOutput) make_output(const std::string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsEngine *engine,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
int retry,
|
||||
bool &precertify);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CocoaGraphicsPipe::init_type();
|
||||
register_type(_type_handle, "TinyCocoaGraphicsPipe",
|
||||
CocoaGraphicsPipe::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 "tinyCocoaGraphicsPipe.I"
|
||||
|
||||
#endif // HAVE_COCOA
|
||||
|
||||
#endif
|
12
panda/src/tinydisplay/tinyCocoaGraphicsWindow.I
Normal file
12
panda/src/tinydisplay/tinyCocoaGraphicsWindow.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 tinyCocoaGraphicsWindow.I
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
88
panda/src/tinydisplay/tinyCocoaGraphicsWindow.h
Normal file
88
panda/src/tinydisplay/tinyCocoaGraphicsWindow.h
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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 tinyCocoaGraphicsWindow.h
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
||||
|
||||
#ifndef TINYCOCOAGRAPHICSWINDOW_H
|
||||
#define TINYCOCOAGRAPHICSWINDOW_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
|
||||
#include "tinyCocoaGraphicsPipe.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "small_vector.h"
|
||||
|
||||
/**
|
||||
* Opens a window on macOS to display the TinyPanda software rendering.
|
||||
*/
|
||||
class EXPCL_TINYDISPLAY TinyCocoaGraphicsWindow : public CocoaGraphicsWindow {
|
||||
public:
|
||||
TinyCocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const std::string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host);
|
||||
virtual ~TinyCocoaGraphicsWindow();
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_flip();
|
||||
virtual bool supports_pixel_zoom() const;
|
||||
|
||||
virtual void process_events();
|
||||
|
||||
protected:
|
||||
virtual void close_window();
|
||||
virtual bool open_window();
|
||||
virtual void pixel_factor_changed();
|
||||
|
||||
private:
|
||||
void create_swap_chain();
|
||||
void do_present();
|
||||
|
||||
private:
|
||||
CGColorSpaceRef _color_space = nil;
|
||||
|
||||
struct SwapBuffer {
|
||||
ZBuffer *_frame_buffer = nullptr;
|
||||
CGDataProviderRef _data_provider = nil;
|
||||
};
|
||||
|
||||
small_vector<SwapBuffer, 2> _swap_chain;
|
||||
int _swap_index = 0;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CocoaGraphicsWindow::init_type();
|
||||
register_type(_type_handle, "TinyCocoaGraphicsWindow",
|
||||
CocoaGraphicsWindow::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 "tinyCocoaGraphicsWindow.I"
|
||||
|
||||
#endif // HAVE_COCOA
|
||||
|
||||
#endif
|
278
panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm
Normal file
278
panda/src/tinydisplay/tinyCocoaGraphicsWindow.mm
Normal file
@ -0,0 +1,278 @@
|
||||
/**
|
||||
* 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 tinyCocoaGraphicsWindow.mm
|
||||
* @author rdb
|
||||
* @date 2023-03-21
|
||||
*/
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef HAVE_COCOA
|
||||
|
||||
#include "tinyCocoaGraphicsWindow.h"
|
||||
#include "tinyGraphicsStateGuardian.h"
|
||||
#include "tinyCocoaGraphicsPipe.h"
|
||||
#include "config_tinydisplay.h"
|
||||
|
||||
#import <QuartzCore/CALayer.h>
|
||||
|
||||
TypeHandle TinyCocoaGraphicsWindow::_type_handle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
TinyCocoaGraphicsWindow::
|
||||
TinyCocoaGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const std::string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host) :
|
||||
CocoaGraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host),
|
||||
_color_space(CGColorSpaceCreateDeviceRGB())
|
||||
{
|
||||
update_pixel_factor();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
TinyCocoaGraphicsWindow::
|
||||
~TinyCocoaGraphicsWindow() {
|
||||
CGColorSpaceRelease(_color_space);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 TinyCocoaGraphicsWindow::
|
||||
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
begin_frame_spam(mode);
|
||||
if (_gsg == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TinyGraphicsStateGuardian *tinygsg;
|
||||
DCAST_INTO_R(tinygsg, _gsg, false);
|
||||
|
||||
tinygsg->_current_frame_buffer = _swap_chain[_swap_index]._frame_buffer;
|
||||
tinygsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame(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 TinyCocoaGraphicsWindow::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
end_frame_spam(mode);
|
||||
nassertv(_gsg != nullptr);
|
||||
|
||||
if (mode == FM_render) {
|
||||
copy_to_textures();
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
if (_swap_chain.size() == 1) {
|
||||
do_present();
|
||||
}
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after begin_flip() has
|
||||
* been called on all windows, to finish the exchange of the front and back
|
||||
* buffers.
|
||||
*
|
||||
* This should cause the window to wait for the flip, if necessary.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
end_flip() {
|
||||
if (_flip_ready) {
|
||||
do_present();
|
||||
_swap_index = (_swap_index + 1) % _swap_chain.size();
|
||||
}
|
||||
|
||||
GraphicsWindow::end_flip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a call to set_pixel_zoom() will be respected, false if it
|
||||
* will be ignored. If this returns false, then get_pixel_factor() will
|
||||
* always return 1.0, regardless of what value you specify for
|
||||
* set_pixel_zoom().
|
||||
*
|
||||
* This may return false if the underlying renderer doesn't support pixel
|
||||
* zooming, or if you have called this on a DisplayRegion that doesn't have
|
||||
* both set_clear_color() and set_clear_depth() enabled.
|
||||
*/
|
||||
bool TinyCocoaGraphicsWindow::
|
||||
supports_pixel_zoom() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do whatever processing is necessary to ensure that the window responds to
|
||||
* user events. Also, honor any requests recently made via
|
||||
* request_properties()
|
||||
*
|
||||
* This function is called only within the window thread.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
process_events() {
|
||||
CocoaGraphicsWindow::process_events();
|
||||
|
||||
if (!_swap_chain.empty()) {
|
||||
int xsize = (get_fb_x_size() + 3) & ~3;
|
||||
int ysize = get_fb_y_size();
|
||||
|
||||
ZBuffer *frame_buffer = _swap_chain[0]._frame_buffer;
|
||||
if (xsize != frame_buffer->xsize ||
|
||||
ysize != frame_buffer->ysize) {
|
||||
create_swap_chain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the window right now. Called from the window thread.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
close_window() {
|
||||
if (_gsg != nullptr) {
|
||||
TinyGraphicsStateGuardian *tinygsg;
|
||||
DCAST_INTO_V(tinygsg, _gsg);
|
||||
tinygsg->_current_frame_buffer = nullptr;
|
||||
_gsg.clear();
|
||||
}
|
||||
|
||||
for (SwapBuffer &swap_buffer : _swap_chain) {
|
||||
CFRelease(swap_buffer._data_provider);
|
||||
ZB_close(swap_buffer._frame_buffer);
|
||||
}
|
||||
|
||||
CocoaGraphicsWindow::close_window();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the window right now. Called from the window thread. Returns true
|
||||
* if the window is successfully opened, or false if there was a problem.
|
||||
*/
|
||||
bool TinyCocoaGraphicsWindow::
|
||||
open_window() {
|
||||
TinyCocoaGraphicsPipe *tinycocoa_pipe;
|
||||
DCAST_INTO_R(tinycocoa_pipe, _pipe, false);
|
||||
|
||||
// GSG CreationInitialization
|
||||
TinyGraphicsStateGuardian *tinygsg;
|
||||
if (_gsg == nullptr) {
|
||||
// There is no old gsg. Create a new one.
|
||||
tinygsg = new TinyGraphicsStateGuardian(_engine, _pipe, nullptr);
|
||||
_gsg = tinygsg;
|
||||
} else {
|
||||
DCAST_INTO_R(tinygsg, _gsg, false);
|
||||
}
|
||||
|
||||
if (!CocoaGraphicsWindow::open_window()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we have a CALayer for drawing into.
|
||||
_view.wantsLayer = YES;
|
||||
_view.layerContentsRedrawPolicy = NSViewLayerContentsRedrawNever;
|
||||
|
||||
create_swap_chain();
|
||||
if (_swap_chain.empty()) {
|
||||
tinydisplay_cat.error()
|
||||
<< "Could not create frame buffer.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
tinygsg->_current_frame_buffer = _swap_chain[_swap_index]._frame_buffer;
|
||||
|
||||
tinygsg->reset_if_new();
|
||||
if (!tinygsg->is_valid()) {
|
||||
close_window();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally when the pixel factor changes.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
pixel_factor_changed() {
|
||||
CocoaGraphicsWindow::pixel_factor_changed();
|
||||
create_swap_chain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a suitable frame buffer for the current window size.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
create_swap_chain() {
|
||||
[_view layer].contents = nil;
|
||||
_swap_index = 0;
|
||||
|
||||
for (SwapBuffer &swap_buffer : _swap_chain) {
|
||||
CFRelease(swap_buffer._data_provider);
|
||||
ZB_close(swap_buffer._frame_buffer);
|
||||
}
|
||||
|
||||
LVecBase2i size = get_fb_size();
|
||||
|
||||
int num_buffers = get_fb_properties().get_back_buffers() + 1;
|
||||
_swap_chain.resize(num_buffers);
|
||||
|
||||
for (SwapBuffer &swap_buffer : _swap_chain) {
|
||||
ZBuffer *frame_buffer = ZB_open(size[0], size[1], ZB_MODE_RGBA, 0, 0, 0, 0);
|
||||
swap_buffer._frame_buffer = frame_buffer;
|
||||
swap_buffer._data_provider =
|
||||
CGDataProviderCreateWithData(nullptr, frame_buffer->pbuf,
|
||||
frame_buffer->linesize * frame_buffer->ysize,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the current framebuffer contents to the layer.
|
||||
*/
|
||||
void TinyCocoaGraphicsWindow::
|
||||
do_present() {
|
||||
LVecBase2i size = get_fb_size();
|
||||
SwapBuffer &swap_buffer = _swap_chain[_swap_index];
|
||||
CGImageRef image =
|
||||
CGImageCreate(size[0], size[1], 8, 32, swap_buffer._frame_buffer->linesize,
|
||||
_color_space, kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst,
|
||||
swap_buffer._data_provider, nullptr, false, kCGRenderingIntentDefault);
|
||||
|
||||
[_view layer].contents = (id)image;
|
||||
CFRelease(image);
|
||||
}
|
||||
|
||||
#endif // HAVE_COCOA
|
Loading…
x
Reference in New Issue
Block a user