mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
glxGraphicsPixmap
This commit is contained in:
parent
ea1f1d632d
commit
6e64da12a6
@ -16,6 +16,7 @@
|
|||||||
config_glxdisplay.cxx config_glxdisplay.h \
|
config_glxdisplay.cxx config_glxdisplay.h \
|
||||||
glxGraphicsBuffer.h glxGraphicsBuffer.I glxGraphicsBuffer.cxx \
|
glxGraphicsBuffer.h glxGraphicsBuffer.I glxGraphicsBuffer.cxx \
|
||||||
glxGraphicsPipe.I glxGraphicsPipe.cxx glxGraphicsPipe.h \
|
glxGraphicsPipe.I glxGraphicsPipe.cxx glxGraphicsPipe.h \
|
||||||
|
glxGraphicsPixmap.h glxGraphicsPixmap.I glxGraphicsPixmap.cxx \
|
||||||
glxGraphicsWindow.h glxGraphicsWindow.I glxGraphicsWindow.cxx \
|
glxGraphicsWindow.h glxGraphicsWindow.I glxGraphicsWindow.cxx \
|
||||||
glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
|
glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \
|
||||||
glxGraphicsStateGuardian.cxx \
|
glxGraphicsStateGuardian.cxx \
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "config_glxdisplay.h"
|
#include "config_glxdisplay.h"
|
||||||
#include "glxGraphicsBuffer.h"
|
#include "glxGraphicsBuffer.h"
|
||||||
#include "glxGraphicsPipe.h"
|
#include "glxGraphicsPipe.h"
|
||||||
|
#include "glxGraphicsPixmap.h"
|
||||||
#include "glxGraphicsWindow.h"
|
#include "glxGraphicsWindow.h"
|
||||||
#include "glxGraphicsStateGuardian.h"
|
#include "glxGraphicsStateGuardian.h"
|
||||||
#include "graphicsPipeSelection.h"
|
#include "graphicsPipeSelection.h"
|
||||||
@ -97,6 +98,7 @@ init_libglxdisplay() {
|
|||||||
glxGraphicsBuffer::init_type();
|
glxGraphicsBuffer::init_type();
|
||||||
#endif // HAVE_GLXFBCONFIG
|
#endif // HAVE_GLXFBCONFIG
|
||||||
glxGraphicsPipe::init_type();
|
glxGraphicsPipe::init_type();
|
||||||
|
glxGraphicsPixmap::init_type();
|
||||||
glxGraphicsWindow::init_type();
|
glxGraphicsWindow::init_type();
|
||||||
glxGraphicsStateGuardian::init_type();
|
glxGraphicsStateGuardian::init_type();
|
||||||
|
|
||||||
|
@ -161,7 +161,6 @@ close_buffer() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool glxGraphicsBuffer::
|
bool glxGraphicsBuffer::
|
||||||
open_buffer() {
|
open_buffer() {
|
||||||
|
|
||||||
glxGraphicsPipe *glx_pipe;
|
glxGraphicsPipe *glx_pipe;
|
||||||
DCAST_INTO_R(glx_pipe, _pipe, false);
|
DCAST_INTO_R(glx_pipe, _pipe, false);
|
||||||
|
|
||||||
@ -170,7 +169,7 @@ open_buffer() {
|
|||||||
if (_gsg == 0) {
|
if (_gsg == 0) {
|
||||||
// There is no old gsg. Create a new one.
|
// There is no old gsg. Create a new one.
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true);
|
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true, false);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
} else {
|
} else {
|
||||||
// If the old gsg has the wrong pixel format, create a
|
// If the old gsg has the wrong pixel format, create a
|
||||||
@ -178,7 +177,7 @@ open_buffer() {
|
|||||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true);
|
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), true, false);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "glxGraphicsPipe.h"
|
#include "glxGraphicsPipe.h"
|
||||||
#include "glxGraphicsWindow.h"
|
#include "glxGraphicsWindow.h"
|
||||||
#include "glxGraphicsBuffer.h"
|
#include "glxGraphicsBuffer.h"
|
||||||
|
#include "glxGraphicsPixmap.h"
|
||||||
#include "glxGraphicsStateGuardian.h"
|
#include "glxGraphicsStateGuardian.h"
|
||||||
#include "config_glxdisplay.h"
|
#include "config_glxdisplay.h"
|
||||||
#include "frameBufferProperties.h"
|
#include "frameBufferProperties.h"
|
||||||
@ -272,24 +273,49 @@ make_output(const string &name,
|
|||||||
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||||
flags, gsg, host);
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GLXFBCONFIG
|
#ifdef HAVE_GLXFBCONFIG
|
||||||
// Third thing to try: a glxGraphicsBuffer
|
// Third thing to try: a glxGraphicsBuffer
|
||||||
|
|
||||||
if (retry == 2) {
|
if (retry == 2) {
|
||||||
if ((!support_rtt)||
|
if (((flags&BF_require_parasite)!=0)||
|
||||||
((flags&BF_require_parasite)!=0)||
|
|
||||||
((flags&BF_require_window)!=0)||
|
((flags&BF_require_window)!=0)||
|
||||||
((flags&BF_resizeable)!=0)||
|
((flags&BF_resizeable)!=0)||
|
||||||
((flags&BF_size_track_host)!=0)||
|
((flags&BF_size_track_host)!=0)) {
|
||||||
((flags&BF_rtt_cumulative)!=0)||
|
|
||||||
((flags&BF_can_bind_every)!=0)) {
|
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
return new glxGraphicsBuffer(engine, this, name, fb_prop, win_prop,
|
||||||
flags, gsg, host);
|
flags, gsg, host);
|
||||||
}
|
}
|
||||||
#endif // HAVE_GLXFBCONFIG
|
#endif // HAVE_GLXFBCONFIG
|
||||||
|
|
||||||
|
// Third thing to try: a glxGraphicsPixmap.
|
||||||
|
if (retry == 3) {
|
||||||
|
if (((flags&BF_require_parasite)!=0)||
|
||||||
|
((flags&BF_require_window)!=0)||
|
||||||
|
((flags&BF_resizeable)!=0)||
|
||||||
|
((flags&BF_size_track_host)!=0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((flags&BF_rtt_cumulative)!=0)||
|
||||||
|
((flags&BF_can_bind_every)!=0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new glxGraphicsPixmap(engine, this, name, fb_prop, win_prop,
|
||||||
|
flags, gsg, host);
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing else left to try.
|
// Nothing else left to try.
|
||||||
return NULL;
|
return NULL;
|
||||||
|
14
panda/src/glxdisplay/glxGraphicsPixmap.I
Normal file
14
panda/src/glxdisplay/glxGraphicsPixmap.I
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Filename: glxGraphicsPixmap.I
|
||||||
|
// Created by: drose (10Mar09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
262
panda/src/glxdisplay/glxGraphicsPixmap.cxx
Normal file
262
panda/src/glxdisplay/glxGraphicsPixmap.cxx
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
// Filename: glxGraphicsPixmap.cxx
|
||||||
|
// Created by: drose (10Mar09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "glxGraphicsPixmap.h"
|
||||||
|
#include "glxGraphicsWindow.h"
|
||||||
|
#include "glxGraphicsStateGuardian.h"
|
||||||
|
#include "config_glxdisplay.h"
|
||||||
|
#include "glxGraphicsPipe.h"
|
||||||
|
|
||||||
|
#include "graphicsPipe.h"
|
||||||
|
#include "glgsg.h"
|
||||||
|
#include "pStatTimer.h"
|
||||||
|
|
||||||
|
TypeHandle glxGraphicsPixmap::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
glxGraphicsPixmap::
|
||||||
|
glxGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||||
|
const string &name,
|
||||||
|
const FrameBufferProperties &fb_prop,
|
||||||
|
const WindowProperties &win_prop,
|
||||||
|
int flags,
|
||||||
|
GraphicsStateGuardian *gsg,
|
||||||
|
GraphicsOutput *host) :
|
||||||
|
GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||||
|
{
|
||||||
|
glxGraphicsPipe *glx_pipe;
|
||||||
|
DCAST_INTO_V(glx_pipe, _pipe);
|
||||||
|
_display = glx_pipe->get_display();
|
||||||
|
_drawable = None;
|
||||||
|
_x_pixmap = None;
|
||||||
|
_glx_pixmap = None;
|
||||||
|
|
||||||
|
// Since the pixmap never gets flipped, we get screenshots from the
|
||||||
|
// same pixmap we draw into.
|
||||||
|
_screenshot_buffer_type = _draw_buffer_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::Destructor
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
glxGraphicsPixmap::
|
||||||
|
~glxGraphicsPixmap() {
|
||||||
|
nassertv(_x_pixmap == None && _glx_pixmap == None);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::begin_frame
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: 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 glxGraphicsPixmap::
|
||||||
|
begin_frame(FrameMode mode, Thread *current_thread) {
|
||||||
|
PStatTimer timer(_make_current_pcollector, current_thread);
|
||||||
|
|
||||||
|
begin_frame_spam(mode);
|
||||||
|
if (_gsg == (GraphicsStateGuardian *)NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glxGraphicsStateGuardian *glxgsg;
|
||||||
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
|
glXMakeCurrent(_display, _glx_pixmap, glxgsg->_context);
|
||||||
|
|
||||||
|
// Now that we have made the context current to a window, we can
|
||||||
|
// reset the GSG state if this is the first time it has been used.
|
||||||
|
// (We can't just call reset() when we construct the GSG, because
|
||||||
|
// reset() requires having a current context.)
|
||||||
|
glxgsg->reset_if_new();
|
||||||
|
|
||||||
|
if (mode == FM_render) {
|
||||||
|
for (int i=0; i<count_textures(); i++) {
|
||||||
|
if (get_rtm_mode(i) == RTM_bind_or_copy) {
|
||||||
|
_textures[i]._rtm_mode = RTM_copy_texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear_cube_map_selection();
|
||||||
|
}
|
||||||
|
|
||||||
|
_gsg->set_current_properties(&get_fb_properties());
|
||||||
|
return _gsg->begin_frame(current_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::end_frame
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: 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 glxGraphicsPixmap::
|
||||||
|
end_frame(FrameMode mode, Thread *current_thread) {
|
||||||
|
end_frame_spam(mode);
|
||||||
|
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
|
||||||
|
|
||||||
|
if (mode == FM_render) {
|
||||||
|
copy_to_textures();
|
||||||
|
}
|
||||||
|
|
||||||
|
_gsg->end_frame(current_thread);
|
||||||
|
|
||||||
|
if (mode == FM_render) {
|
||||||
|
trigger_flip();
|
||||||
|
if (_one_shot) {
|
||||||
|
prepare_for_deletion();
|
||||||
|
}
|
||||||
|
clear_cube_map_selection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::close_buffer
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Closes the pixmap right now. Called from the window
|
||||||
|
// thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void glxGraphicsPixmap::
|
||||||
|
close_buffer() {
|
||||||
|
if (_gsg != (GraphicsStateGuardian *)NULL) {
|
||||||
|
glXMakeCurrent(_display, None, NULL);
|
||||||
|
_gsg.clear();
|
||||||
|
_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glx_pixmap != None) {
|
||||||
|
glXDestroyGLXPixmap(_display, _glx_pixmap);
|
||||||
|
_glx_pixmap = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_x_pixmap != None) {
|
||||||
|
XFreePixmap(_display, _x_pixmap);
|
||||||
|
_x_pixmap = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
_is_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsPixmap::open_buffer
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Opens the pixmap right now. Called from the window
|
||||||
|
// thread. Returns true if the pixmap is successfully
|
||||||
|
// opened, or false if there was a problem.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool glxGraphicsPixmap::
|
||||||
|
open_buffer() {
|
||||||
|
cerr << "open_buffer\n";
|
||||||
|
glxGraphicsPipe *glx_pipe;
|
||||||
|
DCAST_INTO_R(glx_pipe, _pipe, false);
|
||||||
|
|
||||||
|
// GSG Creation/Initialization
|
||||||
|
glxGraphicsStateGuardian *glxgsg;
|
||||||
|
if (_gsg == 0) {
|
||||||
|
// There is no old gsg. Create a new one.
|
||||||
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||||
|
glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
|
||||||
|
_gsg = glxgsg;
|
||||||
|
} else {
|
||||||
|
// If the old gsg has the wrong pixel format, create a
|
||||||
|
// new one that shares with the old gsg.
|
||||||
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
|
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
||||||
|
glxgsg->choose_pixel_format(_fb_properties, _display, glx_pipe->get_screen(), false, true);
|
||||||
|
_gsg = glxgsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XVisualInfo *visual_info = glxgsg->_visual;
|
||||||
|
if (visual_info == NULL) {
|
||||||
|
// No X visual for this fbconfig; how can we create the pixmap?
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "No X visual: cannot create pixmap.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_drawable = glx_pipe->get_root();
|
||||||
|
if (_host != NULL) {
|
||||||
|
cerr << "got host: " << _host->get_type() << "\n";
|
||||||
|
if (_host->is_of_type(glxGraphicsWindow::get_class_type())) {
|
||||||
|
glxGraphicsWindow *win = DCAST(glxGraphicsWindow, _host);
|
||||||
|
_drawable = win->get_xwindow();
|
||||||
|
} else if (_host->is_of_type(glxGraphicsPixmap::get_class_type())) {
|
||||||
|
glxGraphicsPixmap *pix = DCAST(glxGraphicsPixmap, _host);
|
||||||
|
_drawable = pix->_drawable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "creating pixmap, root = " << _drawable
|
||||||
|
<< ", size = " << _x_size << " " << _y_size << ", depth = "
|
||||||
|
<< visual_info->depth << "\n";
|
||||||
|
_x_pixmap = XCreatePixmap(_display, _drawable,
|
||||||
|
_x_size, _y_size, visual_info->depth);
|
||||||
|
cerr << "got " << _x_pixmap << "\n";
|
||||||
|
if (_x_pixmap == None) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Failed to create X pixmap.\n";
|
||||||
|
close_buffer();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cerr << "creating glx pixmap\n";
|
||||||
|
|
||||||
|
#ifdef HAVE_GLXFBCONFIG
|
||||||
|
if (glxgsg->_fbconfig) {
|
||||||
|
// Use the FBConfig to create the pixmap.
|
||||||
|
cerr << "fbconfig\n";
|
||||||
|
_glx_pixmap = glXCreatePixmap(_display, glxgsg->_fbconfig, _x_pixmap, NULL);
|
||||||
|
} else
|
||||||
|
#endif // HAVE_GLXFBCONFIG
|
||||||
|
{
|
||||||
|
// Use the XVisual to create the pixmap.
|
||||||
|
_glx_pixmap = glXCreateGLXPixmap(_display, visual_info, _x_pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "got " << _glx_pixmap << "\n";
|
||||||
|
|
||||||
|
if (_glx_pixmap == None) {
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Failed to create GLX pixmap.\n";
|
||||||
|
close_buffer();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "making current, context = " << glxgsg->_context << "\n";
|
||||||
|
glXMakeCurrent(_display, _glx_pixmap, glxgsg->_context);
|
||||||
|
cerr << "context = " << glxgsg->_context << "\n";
|
||||||
|
glxgsg->reset_if_new();
|
||||||
|
if (!glxgsg->is_valid()) {
|
||||||
|
close_buffer();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!glxgsg->get_fb_properties().verify_hardware_software
|
||||||
|
(_fb_properties, glxgsg->get_gl_renderer())) {
|
||||||
|
close_buffer();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_fb_properties = glxgsg->get_fb_properties();
|
||||||
|
|
||||||
|
_is_valid = true;
|
||||||
|
return true;
|
||||||
|
}
|
75
panda/src/glxdisplay/glxGraphicsPixmap.h
Normal file
75
panda/src/glxdisplay/glxGraphicsPixmap.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Filename: glxGraphicsPixmap.h
|
||||||
|
// Created by: drose (10Mar09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef GLXGRAPHICSPIXMAP_H
|
||||||
|
#define GLXGRAPHICSPIXMAP_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "glxGraphicsPipe.h"
|
||||||
|
#include "graphicsBuffer.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : glxGraphicsPixmap
|
||||||
|
// Description : Another offscreen buffer in the GLX environment. This
|
||||||
|
// creates a Pixmap object, which is probably less
|
||||||
|
// efficient than a GLXPBuffer, so this class is a
|
||||||
|
// second choice to glxGraphicsBuffer. However, this
|
||||||
|
// might be the only option for some graphics drivers.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class glxGraphicsPixmap : public GraphicsBuffer {
|
||||||
|
public:
|
||||||
|
glxGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||||
|
const string &name,
|
||||||
|
const FrameBufferProperties &fb_prop,
|
||||||
|
const WindowProperties &win_prop,
|
||||||
|
int flags,
|
||||||
|
GraphicsStateGuardian *gsg,
|
||||||
|
GraphicsOutput *host);
|
||||||
|
virtual ~glxGraphicsPixmap();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Display *_display;
|
||||||
|
Window _drawable;
|
||||||
|
Pixmap _x_pixmap;
|
||||||
|
GLXPixmap _glx_pixmap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
GraphicsBuffer::init_type();
|
||||||
|
register_type(_type_handle, "glxGraphicsPixmap",
|
||||||
|
GraphicsBuffer::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 "glxGraphicsPixmap.I"
|
||||||
|
|
||||||
|
#endif
|
@ -137,8 +137,8 @@ get_properties(FrameBufferProperties &properties, XVisualInfo *visual) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void glxGraphicsStateGuardian::
|
void glxGraphicsStateGuardian::
|
||||||
get_properties_advanced(FrameBufferProperties &properties,
|
get_properties_advanced(FrameBufferProperties &properties,
|
||||||
bool &pbuffer_supported, bool &slow,
|
bool &pbuffer_supported, bool &pixmap_supported,
|
||||||
fbconfig config) {
|
bool &slow, fbconfig config) {
|
||||||
|
|
||||||
properties.clear();
|
properties.clear();
|
||||||
|
|
||||||
@ -165,22 +165,26 @@ get_properties_advanced(FrameBufferProperties &properties,
|
|||||||
glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
|
glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
|
||||||
glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
|
glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
|
||||||
|
|
||||||
if ((drawable_type & GLX_WINDOW_BIT)==0) {
|
|
||||||
// If we return a set of properties without setting either
|
|
||||||
// rgb_color or indexed_color, then this indicates a visual
|
|
||||||
// that's no good for any kind of rendering.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pbuffer_supported = false;
|
pbuffer_supported = false;
|
||||||
if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
|
if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
|
||||||
pbuffer_supported = true;
|
pbuffer_supported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixmap_supported = false;
|
||||||
|
if ((drawable_type & GLX_PIXMAP_BIT)!=0) {
|
||||||
|
pixmap_supported = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (caveat & GLX_SLOW_CONFIG) {
|
if (caveat & GLX_SLOW_CONFIG) {
|
||||||
slow = true;
|
slow = true;
|
||||||
} else {
|
} else {
|
||||||
slow = false;
|
slow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((drawable_type & GLX_WINDOW_BIT)==0) {
|
||||||
|
// We insist on having a context that will support an onscreen window.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (double_buffer) {
|
if (double_buffer) {
|
||||||
properties.set_back_buffers(1);
|
properties.set_back_buffers(1);
|
||||||
@ -216,8 +220,7 @@ get_properties_advanced(FrameBufferProperties &properties,
|
|||||||
void glxGraphicsStateGuardian::
|
void glxGraphicsStateGuardian::
|
||||||
choose_pixel_format(const FrameBufferProperties &properties,
|
choose_pixel_format(const FrameBufferProperties &properties,
|
||||||
Display *display,
|
Display *display,
|
||||||
int screen,
|
int screen, bool need_pbuffer, bool need_pixmap) {
|
||||||
bool need_pbuffer) {
|
|
||||||
|
|
||||||
_display = display;
|
_display = display;
|
||||||
_screen = screen;
|
_screen = screen;
|
||||||
@ -248,27 +251,34 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
int best_quality = 0;
|
int best_quality = 0;
|
||||||
int best_result = 0;
|
int best_result = 0;
|
||||||
FrameBufferProperties best_props;
|
FrameBufferProperties best_props;
|
||||||
|
|
||||||
if (configs != 0) {
|
if (configs != 0) {
|
||||||
for (int i=0; i<num_configs; i++) {
|
for (int i = 0; i < num_configs; ++i) {
|
||||||
FrameBufferProperties fbprops;
|
FrameBufferProperties fbprops;
|
||||||
bool pbuffer_supported = false, slow = false;
|
bool pbuffer_supported, pixmap_supported, slow;
|
||||||
get_properties_advanced(fbprops, pbuffer_supported, slow, configs[i]);
|
get_properties_advanced(fbprops, pbuffer_supported, pixmap_supported,
|
||||||
|
slow, configs[i]);
|
||||||
if (glxdisplay_cat.is_debug()) {
|
if (glxdisplay_cat.is_debug()) {
|
||||||
const char *pbuffertext = pbuffer_supported ? " (pbuffer)" : "";
|
const char *pbuffertext = pbuffer_supported ? " (pbuffer)" : "";
|
||||||
|
const char *pixmaptext = pixmap_supported ? " (pixmap)" : "";
|
||||||
const char *slowtext = slow ? " (slow)" : "";
|
const char *slowtext = slow ? " (slow)" : "";
|
||||||
glxdisplay_cat.debug()
|
glxdisplay_cat.debug()
|
||||||
<< i << ": " << fbprops << pbuffertext << slowtext << "\n";
|
<< i << ": " << fbprops << pbuffertext << pixmaptext << slowtext << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int quality = fbprops.get_quality(properties);
|
int quality = fbprops.get_quality(properties);
|
||||||
if ((quality > 0)&&(slow)) quality -= 10000000;
|
if ((quality > 0)&&(slow)) quality -= 10000000;
|
||||||
if ((need_pbuffer==0)||(pbuffer_supported)) {
|
|
||||||
if (quality > best_quality) {
|
if (need_pbuffer && !pbuffer_supported) {
|
||||||
best_quality = quality;
|
continue;
|
||||||
best_result = i;
|
}
|
||||||
best_props = fbprops;
|
if (need_pixmap && !pixmap_supported) {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quality > best_quality) {
|
||||||
|
best_quality = quality;
|
||||||
|
best_result = i;
|
||||||
|
best_props = fbprops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,10 +293,13 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
|||||||
_visual = _visuals;
|
_visual = _visuals;
|
||||||
if (_visual) {
|
if (_visual) {
|
||||||
_fbprops = best_props;
|
_fbprops = best_props;
|
||||||
|
cerr << "selected " << _fbconfig << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This really shouldn't happen, so I'm not too careful about cleanup.
|
// This really shouldn't happen, so I'm not too careful about cleanup.
|
||||||
|
glxdisplay_cat.error()
|
||||||
|
<< "Could not create FBConfig context!\n";
|
||||||
_fbconfig = 0;
|
_fbconfig = 0;
|
||||||
_context = 0;
|
_context = 0;
|
||||||
_visual = 0;
|
_visual = 0;
|
||||||
|
@ -78,12 +78,12 @@ public:
|
|||||||
INLINE const FrameBufferProperties &get_fb_properties() const;
|
INLINE const FrameBufferProperties &get_fb_properties() const;
|
||||||
void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
|
void get_properties(FrameBufferProperties &properties, XVisualInfo *visual);
|
||||||
void get_properties_advanced(FrameBufferProperties &properties,
|
void get_properties_advanced(FrameBufferProperties &properties,
|
||||||
bool &supports_pbuffer, bool &slow,
|
bool &pbuffer_supported, bool &pixmap_supported,
|
||||||
fbconfig config);
|
bool &slow, fbconfig config);
|
||||||
void choose_pixel_format(const FrameBufferProperties &properties,
|
void choose_pixel_format(const FrameBufferProperties &properties,
|
||||||
Display *_display,
|
Display *_display,
|
||||||
int _screen,
|
int _screen,
|
||||||
bool need_pbuffer);
|
bool need_pbuffer, bool need_pixmap);
|
||||||
|
|
||||||
glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||||
glxGraphicsStateGuardian *share_with);
|
glxGraphicsStateGuardian *share_with);
|
||||||
|
@ -12,3 +12,13 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: glxGraphicsWindow::get_xwindow
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the X11 Window handle.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE Window glxGraphicsWindow::
|
||||||
|
get_xwindow() const {
|
||||||
|
return _xwindow;
|
||||||
|
}
|
||||||
|
@ -620,7 +620,7 @@ open_window() {
|
|||||||
if (_gsg == 0) {
|
if (_gsg == 0) {
|
||||||
// There is no old gsg. Create a new one.
|
// There is no old gsg. Create a new one.
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, NULL);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false);
|
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false, false);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
} else {
|
} else {
|
||||||
// If the old gsg has the wrong pixel format, create a
|
// If the old gsg has the wrong pixel format, create a
|
||||||
@ -628,17 +628,16 @@ open_window() {
|
|||||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||||
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
if (!glxgsg->get_fb_properties().subsumes(_fb_properties)) {
|
||||||
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
|
||||||
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false);
|
glxgsg->choose_pixel_format(_fb_properties, glx_pipe->get_display(), glx_pipe->get_screen(), false, false);
|
||||||
_gsg = glxgsg;
|
_gsg = glxgsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XVisualInfo *visual_info = glxgsg->_visual;
|
XVisualInfo *visual_info = glxgsg->_visual;
|
||||||
if (visual_info == NULL) {
|
if (visual_info == NULL) {
|
||||||
// No X visual for this fbconfig; how can we open the window?
|
// No X visual for this fbconfig; how can we open the window?
|
||||||
glxdisplay_cat.error()
|
glxdisplay_cat.error()
|
||||||
<< "Cannot open window.\n";
|
<< "No X visual: cannot open window.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Visual *visual = visual_info->visual;
|
Visual *visual = visual_info->visual;
|
||||||
|
@ -45,6 +45,8 @@ public:
|
|||||||
virtual void process_events();
|
virtual void process_events();
|
||||||
virtual void set_properties_now(WindowProperties &properties);
|
virtual void set_properties_now(WindowProperties &properties);
|
||||||
|
|
||||||
|
INLINE Window get_xwindow() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void close_window();
|
virtual void close_window();
|
||||||
virtual bool open_window();
|
virtual bool open_window();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user