mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
add share_with to make_gsg()
This commit is contained in:
parent
e6862c11f9
commit
a4f08870fa
@ -77,7 +77,7 @@ get_auto_flip() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(GraphicsStateGuardian) GraphicsEngine::
|
||||
make_gsg(GraphicsPipe *pipe) {
|
||||
return make_gsg(pipe, get_frame_buffer_properties());
|
||||
return make_gsg(pipe, get_frame_buffer_properties(), NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,9 +183,10 @@ get_threading_model() const {
|
||||
// runs one more time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) GraphicsEngine::
|
||||
make_gsg(GraphicsPipe *pipe, const FrameBufferProperties &properties) {
|
||||
make_gsg(GraphicsPipe *pipe, const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
// TODO: ask the draw thread to make the GSG.
|
||||
PT(GraphicsStateGuardian) gsg = pipe->make_gsg(properties);
|
||||
PT(GraphicsStateGuardian) gsg = pipe->make_gsg(properties, share_with);
|
||||
if (gsg != (GraphicsStateGuardian *)NULL) {
|
||||
gsg->_threading_model = get_threading_model();
|
||||
gsg->_pipe = pipe;
|
||||
|
@ -71,7 +71,8 @@ PUBLISHED:
|
||||
|
||||
INLINE PT(GraphicsStateGuardian) make_gsg(GraphicsPipe *pipe);
|
||||
PT(GraphicsStateGuardian) make_gsg(GraphicsPipe *pipe,
|
||||
const FrameBufferProperties &properties);
|
||||
const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
|
||||
GraphicsWindow *make_window(GraphicsStateGuardian *gsg, const string &name,
|
||||
int sort);
|
||||
|
@ -124,7 +124,8 @@ make_device(void *scrn) {
|
||||
// be called in the draw thread for the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) GraphicsPipe::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
display_cat.error()
|
||||
<< "make_gsg() unimplemented by " << get_type() << "\n";
|
||||
return NULL;
|
||||
|
@ -93,7 +93,8 @@ protected:
|
||||
// The make_window() and make_gsg() interfaces on GraphicsPipe are
|
||||
// protected; don't try to call them directly. Instead, use
|
||||
// the interface on GraphicsEngine to make a new window or gsg.
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual void close_gsg(GraphicsStateGuardian *gsg);
|
||||
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg,
|
||||
const string &name);
|
||||
|
@ -85,7 +85,13 @@ make_window(GraphicsStateGuardian *gsg, const string &name) {
|
||||
|
||||
|
||||
PT(GraphicsStateGuardian) wdxGraphicsPipe7::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
wdxdisplay7_cat.error()
|
||||
<< "wdxGraphicsPipe7 does not presently support sharing texture contexts.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FrameBufferProperties really belongs as part of the window/renderbuffer specification
|
||||
// put here because of GLX multithreading requirement
|
||||
|
@ -34,7 +34,8 @@ public:
|
||||
|
||||
virtual string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg, const string &name);
|
||||
|
@ -801,8 +801,13 @@ make_device(void *scrn) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
PT(GraphicsStateGuardian) wdxGraphicsPipe8::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
wdxdisplay8_cat.error()
|
||||
<< "wdxGraphicsPipe8 does not presently support sharing texture contexts.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FrameBufferProperties really belongs as part of the window/renderbuffer specification
|
||||
// put here because of GLX multithreading requirement
|
||||
|
@ -48,7 +48,8 @@ public:
|
||||
virtual string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual PT(GraphicsDevice) make_device(void *scrn);
|
||||
|
||||
bool find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode,
|
||||
|
@ -820,8 +820,13 @@ make_device(void *scrn) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
PT(GraphicsStateGuardian) wdxGraphicsPipe9::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
wdxdisplay9_cat.error()
|
||||
<< "wdxGraphicsPipe9 does not presently support sharing texture contexts.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FrameBufferProperties really belongs as part of the window/renderbuffer specification
|
||||
// put here because of GLX multithreading requirement
|
||||
|
@ -48,7 +48,8 @@ public:
|
||||
virtual string get_interface_name() const;
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual PT(GraphicsDevice) make_device(void *scrn);
|
||||
|
||||
bool find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode,
|
||||
|
@ -161,11 +161,27 @@ pipe_constructor() {
|
||||
// be called in the draw thread for the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) glxGraphicsPipe::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
if (!_is_valid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
glxGraphicsStateGuardian *share_gsg = NULL;
|
||||
GLXContext share_context = NULL;
|
||||
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
if (!share_with->is_exact_type(glxGraphicsStateGuardian::get_class_type())) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Cannot share context between glxGraphicsStateGuardian and "
|
||||
<< share_with->get_type() << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DCAST_INTO_R(share_gsg, share_with, NULL);
|
||||
share_context = share_gsg->_context;
|
||||
}
|
||||
|
||||
FrameBufferProperties new_properties = properties;
|
||||
GLXFBConfig fbconfig = choose_fbconfig(new_properties);
|
||||
if (fbconfig == None) {
|
||||
@ -174,7 +190,8 @@ make_gsg(const FrameBufferProperties &properties) {
|
||||
|
||||
// Attempt to create a GL context.
|
||||
GLXContext context =
|
||||
glXCreateNewContext(_display, fbconfig, GLX_RGBA_TYPE, NULL, GL_TRUE);
|
||||
glXCreateNewContext(_display, fbconfig, GLX_RGBA_TYPE, share_context,
|
||||
GL_TRUE);
|
||||
if (context == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Could not create GL context.\n";
|
||||
@ -183,7 +200,7 @@ make_gsg(const FrameBufferProperties &properties) {
|
||||
|
||||
// Now we can make a GSG.
|
||||
PT(glxGraphicsStateGuardian) gsg =
|
||||
new glxGraphicsStateGuardian(new_properties, NULL, context, fbconfig,
|
||||
new glxGraphicsStateGuardian(new_properties, share_gsg, context, fbconfig,
|
||||
_display, _screen);
|
||||
return gsg.p();
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ public:
|
||||
INLINE Atom get_wm_delete_window() const;
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg,
|
||||
const string &name);
|
||||
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
|
||||
|
@ -80,8 +80,23 @@ pipe_constructor() {
|
||||
// be called in the draw thread for the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) OsMesaGraphicsPipe::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
return new OSMesaGraphicsStateGuardian(properties);
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
|
||||
OSMesaGraphicsStateGuardian *share_gsg = NULL;
|
||||
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
if (!share_with->is_exact_type(OSMesaGraphicsStateGuardian::get_class_type())) {
|
||||
mesadisplay_cat.error()
|
||||
<< "Cannot share context between OSMesaGraphicsStateGuardian and "
|
||||
<< share_with->get_type() << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DCAST_INTO_R(share_gsg, share_with, NULL);
|
||||
}
|
||||
|
||||
return new OSMesaGraphicsStateGuardian(properties, share_gsg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -46,7 +46,8 @@ public:
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
|
||||
const string &name,
|
||||
int x_size, int y_size, bool want_texture);
|
||||
|
@ -26,10 +26,17 @@ TypeHandle OSMesaGraphicsStateGuardian::_type_handle;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
OSMesaGraphicsStateGuardian::
|
||||
OSMesaGraphicsStateGuardian(const FrameBufferProperties &properties) :
|
||||
OSMesaGraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
OSMesaGraphicsStateGuardian *share_with) :
|
||||
MesaGraphicsStateGuardian(properties)
|
||||
{
|
||||
_context = OSMesaCreateContext(OSMESA_RGBA, NULL);
|
||||
OSMesaContext share_context = NULL;
|
||||
if (share_with != (OSMesaGraphicsStateGuardian *)NULL) {
|
||||
share_context = share_with->_context;
|
||||
_prepared_objects = share_with->get_prepared_objects();
|
||||
}
|
||||
|
||||
_context = OSMesaCreateContext(OSMESA_RGBA, share_context);
|
||||
|
||||
// I think OSMesa always creates single-buffered contexts. I don't
|
||||
// see any documentation to this effect, but it seems to be the
|
||||
|
@ -29,7 +29,8 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAMESA OSMesaGraphicsStateGuardian : public MesaGraphicsStateGuardian {
|
||||
public:
|
||||
OSMesaGraphicsStateGuardian(const FrameBufferProperties &properties);
|
||||
OSMesaGraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
OSMesaGraphicsStateGuardian *share_with);
|
||||
virtual ~OSMesaGraphicsStateGuardian();
|
||||
|
||||
OSMesaContext _context;
|
||||
|
@ -81,11 +81,25 @@ pipe_constructor() {
|
||||
// be called in the draw thread for the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(GraphicsStateGuardian) wglGraphicsPipe::
|
||||
make_gsg(const FrameBufferProperties &properties) {
|
||||
make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with) {
|
||||
if (!_is_valid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wglGraphicsStateGuardian *share_gsg = NULL;
|
||||
|
||||
if (share_with != (GraphicsStateGuardian *)NULL) {
|
||||
if (!share_with->is_exact_type(wglGraphicsStateGuardian::get_class_type())) {
|
||||
wgldisplay_cat.error()
|
||||
<< "Cannot share context between wglGraphicsStateGuardian and "
|
||||
<< share_with->get_type() << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DCAST_INTO_R(share_gsg, share_with, NULL);
|
||||
}
|
||||
|
||||
// Make a copy of the supplied properties so we can possibly modify
|
||||
// them to suit our available properties.
|
||||
FrameBufferProperties new_properties = properties;
|
||||
@ -109,7 +123,14 @@ make_gsg(const FrameBufferProperties &properties) {
|
||||
}
|
||||
|
||||
PT(wglGraphicsStateGuardian) gsg =
|
||||
new wglGraphicsStateGuardian(properties, pfnum);
|
||||
new wglGraphicsStateGuardian(properties, share_gsg, pfnum);
|
||||
|
||||
// Ideally, we should be able to detect whether the share_gsg will
|
||||
// be successful, and return NULL if it won't work. But we can't do
|
||||
// that yet, because we can't try to actually share the gsg until we
|
||||
// create the context, for which we need to have a window. That
|
||||
// means the app will just have to trust it will work; if it doesn't
|
||||
// work, too bad.
|
||||
|
||||
return gsg.p();
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ public:
|
||||
static PT(GraphicsPipe) pipe_constructor();
|
||||
|
||||
protected:
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties);
|
||||
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
|
||||
GraphicsStateGuardian *share_with);
|
||||
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg,
|
||||
const string &name);
|
||||
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
|
||||
|
@ -28,8 +28,10 @@ TypeHandle wglGraphicsStateGuardian::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
wglGraphicsStateGuardian::
|
||||
wglGraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
wglGraphicsStateGuardian *share_with,
|
||||
int pfnum) :
|
||||
GLGraphicsStateGuardian(properties),
|
||||
_share_with(share_with),
|
||||
_pfnum(pfnum)
|
||||
{
|
||||
_made_context = false;
|
||||
@ -163,4 +165,72 @@ make_context(HDC hdc) {
|
||||
<< "Could not create GL context.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Now share texture context with the indicated GSG.
|
||||
if (_share_with != (wglGraphicsStateGuardian *)NULL) {
|
||||
HGLRC share_context = _share_with->get_share_context();
|
||||
if (share_context == NULL) {
|
||||
// Whoops, the target context hasn't yet made its own context.
|
||||
// In that case, it will share context with us.
|
||||
_share_with->redirect_share_pool(this);
|
||||
|
||||
} else {
|
||||
if (!wglShareLists(share_context, _context)) {
|
||||
wgldisplay_cat.error()
|
||||
<< "Could not share texture contexts between wglGraphicsStateGuardians.\n";
|
||||
// Too bad we couldn't detect this error sooner. Now there's
|
||||
// really no way to tell the application it's hosed.
|
||||
|
||||
} else {
|
||||
_prepared_objects = _share_with->get_prepared_objects();
|
||||
}
|
||||
}
|
||||
|
||||
_share_with = (wglGraphicsStateGuardian *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsStateGuardian::get_share_context
|
||||
// Access: Private
|
||||
// Description: Returns a wgl context handle for the purpose of
|
||||
// sharing texture context with this GSG. This will
|
||||
// either be the GSG's own context handle, if it exists
|
||||
// yet, or the context handle of some other GSG that
|
||||
// this GSG is planning to share with. If this returns
|
||||
// NULL, none of the GSG's in this share pool have yet
|
||||
// created their context.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HGLRC wglGraphicsStateGuardian::
|
||||
get_share_context() const {
|
||||
if (_made_context) {
|
||||
return _context;
|
||||
}
|
||||
if (_share_with != (wglGraphicsStateGuardian *)NULL) {
|
||||
return _share_with->get_share_context();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsStateGuardian::redirect_share_pool
|
||||
// Access: Private
|
||||
// Description: Directs the GSG (along with all GSG's it is planning
|
||||
// to share a texture context with) to share texture
|
||||
// context with the indicated GSG.
|
||||
//
|
||||
// This assumes that this GSG's context has not yet been
|
||||
// created, and neither have any of the GSG's it is
|
||||
// planning to share texture context with; but the
|
||||
// graphics context for the indicated GSG has already
|
||||
// been created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void wglGraphicsStateGuardian::
|
||||
redirect_share_pool(wglGraphicsStateGuardian *share_with) {
|
||||
nassertv(!_made_context);
|
||||
if (_share_with != (wglGraphicsStateGuardian *)NULL) {
|
||||
_share_with->redirect_share_pool(share_with);
|
||||
} else {
|
||||
_share_with = share_with;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class wglGraphicsStateGuardian : public GLGraphicsStateGuardian {
|
||||
public:
|
||||
wglGraphicsStateGuardian(const FrameBufferProperties &properties, int pfnum);
|
||||
wglGraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
wglGraphicsStateGuardian *share_with,
|
||||
int pfnum);
|
||||
virtual ~wglGraphicsStateGuardian();
|
||||
|
||||
INLINE int get_pfnum() const;
|
||||
@ -48,6 +50,13 @@ protected:
|
||||
|
||||
private:
|
||||
void make_context(HDC hdc);
|
||||
HGLRC get_share_context() const;
|
||||
void redirect_share_pool(wglGraphicsStateGuardian *share_with);
|
||||
|
||||
// We have to save a pointer to the GSG we intend to share texture
|
||||
// context with, since we don't create our own context in the
|
||||
// constructor.
|
||||
PT(wglGraphicsStateGuardian) _share_with;
|
||||
|
||||
// All windows that share a particular GL context must also share
|
||||
// the same pixel format; therefore, we store the pixel format
|
||||
|
Loading…
x
Reference in New Issue
Block a user