Buffer overhaul phase one

This commit is contained in:
Josh Yelon 2006-03-20 17:56:51 +00:00
parent 7c6eef84a4
commit a176d3627c
43 changed files with 757 additions and 467 deletions

View File

@ -28,9 +28,12 @@ TypeHandle GraphicsBuffer::_type_handle;
// GraphicsEngine::make_buffer() function.
////////////////////////////////////////////////////////////////////
GraphicsBuffer::
GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name, int x_size, int y_size) :
GraphicsOutput(pipe, gsg, name)
GraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsOutput(pipe, name, x_size, y_size, flags, gsg, host)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
@ -38,13 +41,9 @@ GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
if (display_cat.is_debug()) {
display_cat.debug()
<< "Creating new offscreen buffer " << get_name()
<< " using GSG " << (void *)gsg << "\n";
<< "Creating new offscreen buffer " << get_name() << "\n";
}
_x_size = x_size;
_y_size = y_size;
_has_size = true;
_default_display_region->compute_pixels(_x_size, _y_size);
_open_request = OR_none;
}

View File

@ -33,8 +33,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsBuffer : public GraphicsOutput {
protected:
GraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name, int x_size, int y_size);
GraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
PUBLISHED:
virtual ~GraphicsBuffer();

View File

@ -78,6 +78,19 @@ get_portal_cull() const {
return _portal_enabled;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::close_gsg
// Access: Published
// Description: Calls GraphicsPipe::close_gsg() on the indicated pipe
// and GSG. This function mainly exists to allow
// GraphicsEngine::WindowRenderer to call the protected
// method GraphicsPipe::close_gsg().
////////////////////////////////////////////////////////////////////
INLINE void GraphicsEngine::
close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) {
pipe->close_gsg(gsg);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_gsg
// Access: Published
@ -103,20 +116,50 @@ make_gsg(GraphicsPipe *pipe) {
return make_gsg(pipe, get_frame_buffer_properties(), NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::close_gsg
// Function: GraphicsEngine::make_window
// Access: Published
// Description: Calls GraphicsPipe::close_gsg() on the indicated pipe
// and GSG. This function mainly exists to allow
// GraphicsEngine::WindowRenderer to call the protected
// method GraphicsPipe::close_gsg().
// Description: Syntactic shorthand for make_output
////////////////////////////////////////////////////////////////////
INLINE void GraphicsEngine::
close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg) {
pipe->close_gsg(gsg);
INLINE GraphicsWindow *GraphicsEngine::
make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
// The hardwired size here is never used.
GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
gsg->get_properties(), 50, 50,
GraphicsPipe::BF_require_window,
gsg, NULL);
return DCAST(GraphicsWindow, result);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_buffer
// Access: Published
// Description: Syntactic shorthand for make_output
////////////////////////////////////////////////////////////////////
INLINE GraphicsOutput *GraphicsEngine::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int sort, int x_size, int y_size) {
GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
gsg->get_properties(), x_size, y_size,
GraphicsPipe::BF_refuse_window,
gsg, NULL);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_parasite
// Access: Published
// Description: Syntactic shorthand for make_buffer.
////////////////////////////////////////////////////////////////////
INLINE GraphicsOutput *GraphicsEngine::
make_parasite(GraphicsOutput *host, const string &name,
int sort, int x_size, int y_size) {
GraphicsOutput *result = make_output(host->get_gsg()->get_pipe(), name, sort,
host->get_gsg()->get_properties(), x_size, y_size,
GraphicsPipe::BF_require_parasite,
host->get_gsg(), host);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::Callback::Constructor
@ -152,3 +195,4 @@ INLINE void GraphicsEngine::Callback::
do_callback() const {
(*_func)(_data);
}

View File

@ -238,120 +238,160 @@ make_gsg(GraphicsPipe *pipe, const FrameBufferProperties &properties,
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_window
// Function: GraphicsEngine::make_output
// Access: Published
// Description: Creates a new window using the indicated
// GraphicsStateGuardian and returns it. The
// GraphicsEngine becomes the owner of the window; it
// will persist at least until remove_window() is called
// later.
////////////////////////////////////////////////////////////////////
GraphicsWindow *GraphicsEngine::
make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
GraphicsThreadingModel threading_model = get_threading_model();
nassertr(gsg != (GraphicsStateGuardian *)NULL, NULL);
nassertr(this == gsg->get_engine(), NULL);
nassertr(threading_model.get_draw_name() ==
gsg->get_threading_model().get_draw_name(), NULL);
// TODO: ask the window thread to make the window.
PT(GraphicsWindow) window = gsg->get_pipe()->make_window(gsg, name);
if (window != (GraphicsWindow *)NULL) {
window->_sort = sort;
do_add_window(window, gsg, threading_model);
}
return window;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_buffer
// Access: Published
// Description: Creates a new offscreen buffer using the indicated
// GraphicsStateGuardian and returns it. The
// GraphicsEngine becomes the owner of the buffer; it
// will persist at least until remove_window() is called
// later.
// Description: Creates a new window (or buffer) and returns it.
// The GraphicsEngine becomes the owner of the window,
// it will persist at least until remove_window() is
// called later.
//
// This usually returns a GraphicsBuffer object, but it
// may actually return a GraphicsWindow if show-buffers
// is configured true.
// If a null pointer is supplied for the gsg, then this
// routine will create a new gsg.
//
// This routine is only called from the app thread.
////////////////////////////////////////////////////////////////////
GraphicsOutput *GraphicsEngine::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int sort, int x_size, int y_size) {
// I'll remove this permanently in a few days. - Josh
// if (show_buffers) {
// GraphicsWindow *window = make_window(gsg, name, sort);
// if (window != (GraphicsWindow *)NULL) {
// WindowProperties props;
// props.set_size(x_size, y_size);
// props.set_fixed_size(true);
// props.set_title(name);
// window->request_properties(props);
// return window;
// }
// }
make_output(GraphicsPipe *pipe,
const string &name, int sort,
const FrameBufferProperties &prop,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) {
// The code here is tricky because the gsg that is passed in
// might be in the uninitialized state. As a result,
// pipe::make_output may not be able to tell which DirectX
// capabilities or OpenGL extensions are supported and which
// are not. Worse yet, it can't query the API, because that
// can only be done from the draw thread, and this is the app
// thread.
//
// So here's the workaround: this routine calls pipe::make_output,
// which returns a "non-certified" window. That means that
// the pipe doesn't promise that the draw thread will actually
// succeed in initializing the window. This routine then calls
// open_windows, which attempts to initialize the window.
//
// If open_windows fails to initialize the window, then
// this routine will ask pipe::make_output to try again, this
// time using a different set of OpenGL extensions or DirectX
// capabilities. This is what the "retry" parameter to
// pipe::make_output is for - it specifies, in an abstract
// manner, which set of capabilties/extensions to try.
//
// The only problem with this design is that it requires the
// engine to call open_windows, which is slow. To make
// things faster, we can ask pipe::make_output to "precertify"
// its creations. If we ask it to precertify, then it guarantees
// that the windows it returns will not fail in open_windows.
// However, we can only ask for precertification if we are
// passing it an already-initialized gsg. Long story short,
// if you want make_output to be fast, use an
// already-initialized gsg.
// Simplify the input parameters.
if ((x_size==0) || (y_size == 0)) {
flags |= GraphicsPipe::BF_size_track_host;
}
if (host != 0) {
host = host->get_host();
}
// Sanity check everything.
GraphicsThreadingModel threading_model = get_threading_model();
nassertr(gsg != (GraphicsStateGuardian *)NULL, NULL);
nassertr(this == gsg->get_engine(), NULL);
nassertr(threading_model.get_draw_name() ==
gsg->get_threading_model().get_draw_name(), NULL);
nassertr(pipe != (GraphicsPipe *)NULL, NULL);
if (gsg != (GraphicsStateGuardian *)NULL) {
nassertr(pipe == gsg->get_pipe(), NULL);
nassertr(this == gsg->get_engine(), NULL);
nassertr(prop == gsg->get_properties(), NULL);
nassertr(threading_model.get_draw_name() ==
gsg->get_threading_model().get_draw_name(), NULL);
}
if (host != (GraphicsOutput *)NULL) {
nassertr(gsg == host->get_gsg(), NULL);
}
// If the gsg is null, then create one.
if (gsg == (GraphicsStateGuardian *)NULL) {
gsg = make_gsg(pipe, prop);
}
// A thread could modify these flags while we create the
// buffer. So we do a single atomic fetch here.
bool precertify = gsg->_is_valid && (!gsg->_needs_reset);
// Determine if a parasite buffer meets the user's specs.
// TODO: ask the window thread to make the buffer.
PT(GraphicsBuffer) buffer =
gsg->get_pipe()->make_buffer(gsg, name, x_size, y_size);
if (buffer != (GraphicsBuffer *)NULL) {
bool can_use_parasite = false;
if ((host != 0)&&
((flags&GraphicsPipe::BF_require_window)==0)&&
((flags&GraphicsPipe::BF_refuse_parasite)==0)&&
((flags&GraphicsPipe::BF_need_aux_rgba_MASK)==0)&&
((flags&GraphicsPipe::BF_need_aux_hrgba_MASK)==0)&&
((flags&GraphicsPipe::BF_need_aux_float_MASK)==0)&&
((flags&GraphicsPipe::BF_can_bind_color)==0)&&
((flags&GraphicsPipe::BF_can_bind_every)==0)) {
can_use_parasite = true;
}
// If parasite buffers are preferred, then try a parasite first.
if ((prefer_parasite_buffer) &&
(can_use_parasite) &&
(x_size <= host->get_x_size())&&
(y_size <= host->get_y_size())) {
ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size, flags);
buffer->_sort = sort;
do_add_window(buffer, gsg, threading_model);
return buffer;
}
return buffer;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::make_parasite
// Access: Published
// Description: Creates a new offscreen parasite buffer based on the
// indicated host. See parasiteBuffer.h. The
// GraphicsEngine becomes the owner of the buffer; it
// will persist at least until remove_window() is called
// later.
//
// This usually returns a ParasiteBuffer object, but it
// may actually return a GraphicsWindow if show-buffers
// is configured true.
////////////////////////////////////////////////////////////////////
GraphicsOutput *GraphicsEngine::
make_parasite(GraphicsOutput *host, const string &name,
int sort, int x_size, int y_size) {
GraphicsStateGuardian *gsg = host->get_gsg();
// Ask the pipe to create a window.
for (int retry=0; retry<10; retry++) {
PT(GraphicsOutput) window =
pipe->make_output(name, x_size, y_size, flags, gsg, host, retry, precertify);
if (window != (GraphicsOutput *)NULL) {
window->_sort = sort;
do_add_window(window, gsg, threading_model);
if (precertify) {
return window;
}
open_windows();
if (window->is_valid()) {
return window;
}
// No good; delete the window and keep trying.
bool removed = remove_window(window);
nassertr(removed, NULL);
}
}
// Parasite buffers were not preferred, but the pipe could not
// create a window to the user's specs. Try a parasite as a
// last hope.
if (can_use_parasite) {
if (x_size > host->get_x_size()) {
x_size = Texture::down_to_power_2(host->get_x_size());
}
if (y_size > host->get_y_size()) {
y_size = Texture::down_to_power_2(host->get_y_size());
}
ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size, flags);
buffer->_sort = sort;
do_add_window(buffer, gsg, threading_model);
return buffer;
}
// I'll remove this permanently in a few days. - Josh
// if (show_buffers) {
// GraphicsWindow *window = make_window(gsg, name, sort);
// if (window != (GraphicsWindow *)NULL) {
// WindowProperties props;
// props.set_size(x_size, y_size);
// props.set_fixed_size(true);
// props.set_title(name);
// window->request_properties(props);
//
// return window;
// }
// }
GraphicsThreadingModel threading_model = get_threading_model();
nassertr(gsg != (GraphicsStateGuardian *)NULL, NULL);
nassertr(this == gsg->get_engine(), NULL);
nassertr(threading_model.get_draw_name() ==
gsg->get_threading_model().get_draw_name(), NULL);
ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size);
buffer->_sort = sort;
do_add_window(buffer, gsg, threading_model);
return buffer;
// Could not create a window to the user's specs.
return NULL;
}
////////////////////////////////////////////////////////////////////
@ -1100,8 +1140,8 @@ draw_bins(GraphicsOutput *win, DisplayRegion *dr) {
// Function: GraphicsEngine::make_contexts
// Access: Private
// Description: Called in the draw thread, this calls make_context()
// on each window on the list to guarantee its graphics
// context gets created.
// on each window on the list to guarantee its gsg and
// graphics context both get created.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
make_contexts(const GraphicsEngine::Windows &wlist) {
@ -1429,7 +1469,8 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup,
// Description: An internal function called by make_window() and
// make_buffer() and similar functions to add the
// newly-created GraphicsOutput object to the engine's
// tables.
// list of windows, and to request that the window be
// opened.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
@ -1477,6 +1518,7 @@ do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
window->request_open();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::do_remove_window
// Access: Private

View File

@ -72,18 +72,29 @@ PUBLISHED:
INLINE void set_portal_cull(bool value);
INLINE bool get_portal_cull() const;
INLINE PT(GraphicsStateGuardian) make_gsg(GraphicsPipe *pipe);
PT(GraphicsStateGuardian) make_gsg(GraphicsPipe *pipe,
const FrameBufferProperties &properties,
GraphicsStateGuardian *share_with = NULL);
GraphicsWindow *make_window(GraphicsStateGuardian *gsg, const string &name,
int sort);
GraphicsOutput *make_buffer(GraphicsStateGuardian *gsg, const string &name,
int sort, int x_size, int y_size);
GraphicsOutput *make_parasite(GraphicsOutput *host, const string &name,
int sort, int x_size, int y_size);
GraphicsOutput *make_output(GraphicsPipe *pipe,
const string &name, int sort,
const FrameBufferProperties &prop,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg = 0,
GraphicsOutput *host = 0);
// Syntactic shorthand versions of make_output
INLINE GraphicsWindow *make_window(GraphicsStateGuardian *gsg,
const string &name, int sort);
INLINE GraphicsOutput *make_buffer(GraphicsStateGuardian *gsg,
const string &name, int sort,
int x_size, int y_size);
INLINE GraphicsOutput *make_parasite(GraphicsOutput *host,
const string &name, int sort,
int x_size, int y_size);
bool remove_window(GraphicsOutput *window);
void remove_all_windows();
void reset_all_windows(bool swapchain);
@ -282,9 +293,9 @@ private:
Windows _draw; // draw stage
Windows _window; // window stage, i.e. process windowing events
// These two are not kept sorted.
Windows _pending_release; // moved from _draw, pending release_gsg.
Windows _pending_close; // moved from _window, pending close.
// These are not kept sorted.
Windows _pending_release; // moved from _draw, pending release_gsg.
Windows _pending_close; // moved from _window, pending close.
GSGs _gsgs; // draw stage

View File

@ -69,17 +69,22 @@ static CubeFaceDef cube_faces[6] = {
// GraphicsEngine::make_window() function.
////////////////////////////////////////////////////////////////////
GraphicsOutput::
GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) {
GraphicsOutput(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) {
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
#endif
_pipe = pipe;
_gsg = gsg;
_host = host;
_name = name;
_x_size = 0;
_y_size = 0;
_has_size = false;
_creation_flags = flags;
_x_size = x_size;
_y_size = y_size;
_has_size = false; // Need to look into what this does.
_is_valid = false;
_flip_ready = false;
_cube_map_index = -1;
@ -99,8 +104,10 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
if (gsg->get_properties().is_single_buffered()) {
// Single buffered; we must draw into the front buffer.
_draw_buffer_type = RenderBuffer::T_front;
} else {
_draw_buffer_type = RenderBuffer::T_back;
}
// We start out with one DisplayRegion that covers the whole window,
// which we may use internally for full-window operations like
// clear() and get_screenshot().
@ -242,6 +249,10 @@ add_render_texture(Texture *tex, RenderTextureMode mode) {
tex->set_x_size(get_x_size());
tex->set_y_size(get_y_size());
if ((mode == RTM_bind_or_copy)&&(support_render_texture==0)) {
mode = RTM_copy_texture;
}
RenderTexture result;
result._texture = tex;
result._rtm_mode = mode;
@ -670,122 +681,19 @@ get_texture_card() {
GraphicsOutput *GraphicsOutput::
make_texture_buffer(const string &name, int x_size, int y_size,
Texture *tex, bool to_ram) {
GraphicsStateGuardian *gsg = get_gsg();
GraphicsEngine *engine = gsg->get_engine();
GraphicsOutput *host = get_host();
// The new buffer should be drawn before this buffer is drawn. If
// the user requires more control than this, he can set the sort
// value himself.
int sort = get_sort() - 1;
GraphicsOutput *buffer = NULL;
if ((x_size == 0) && (y_size == 0)) {
// Currently, only parasite buffers support the tracking of the
// host window size. If the user requests this, we have to use a
// parasite buffer.
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
return buffer;
}
// I'll remove this permanently in a few days. - Josh
// if (show_buffers) {
// // If show_buffers is true, just go ahead and call make_buffer(),
// // since it all amounts to the same thing anyway--this will
// // actually create a new GraphicsWindow.
// buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
// buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
// return buffer;
// }
bool allow_bind =
(prefer_texture_buffer && support_render_texture &&
gsg->get_supports_render_texture() && !to_ram);
// If the user so indicated in the Config.prc file, try to create a
// parasite buffer first. We can only do this if the requested size
// fits within the available framebuffer size. Also, don't do this
// if we want to try using render-to-a-texture mode, since using a
// ParasiteButter will preclude that.
if (prefer_parasite_buffer && !allow_bind &&
(x_size <= host->get_x_size() && y_size <= host->get_y_size())) {
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
if (buffer != (GraphicsOutput *)NULL) {
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
return buffer;
}
}
// Attempt to create a single-buffered offscreen buffer.
if (prefer_single_buffer) {
FrameBufferProperties sb_props = gsg->get_properties();
int orig_mode = sb_props.get_frame_buffer_mode();
int sb_mode = (orig_mode & ~FrameBufferProperties::FM_buffer) | FrameBufferProperties::FM_single_buffer;
sb_props.set_frame_buffer_mode(sb_mode);
if (sb_mode != orig_mode) {
PT(GraphicsStateGuardian) sb_gsg =
engine->make_gsg(gsg->get_pipe(), sb_props, gsg);
if (sb_gsg != (GraphicsStateGuardian *)NULL) {
buffer = engine->make_buffer(sb_gsg, name, sort, x_size, y_size);
if (buffer != (GraphicsOutput *)NULL) {
// Check the buffer for goodness.
if (allow_bind) {
buffer->add_render_texture(tex, RTM_bind_or_copy);
} else {
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
}
engine->open_windows();
if (buffer->is_valid()) {
return buffer;
}
// No good; delete the buffer and keep trying.
bool removed = engine->remove_window(buffer);
nassertr(removed, NULL);
buffer = (GraphicsOutput *)NULL;
}
}
}
}
// All right, attempt to create an offscreen buffer, using the same
// GSG. This will be a double-buffered offscreen buffer, if the
// source window is double-buffered.
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size);
GraphicsOutput *buffer = get_gsg()->get_engine()->
make_output(get_gsg()->get_pipe(),
name, get_sort()-1,
get_gsg()->get_properties(),
x_size, y_size, GraphicsPipe::BF_refuse_window,
get_gsg(), get_host());
if (buffer != (GraphicsOutput *)NULL) {
if (allow_bind) {
buffer->add_render_texture(tex, RTM_bind_or_copy);
} else {
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
}
engine->open_windows();
if (buffer->is_valid()) {
return buffer;
}
bool removed = engine->remove_window(buffer);
nassertr(removed, NULL);
buffer = (GraphicsOutput *)NULL;
}
// Looks like we have to settle for a parasite buffer.
// make sure the size is not bigger than the display buffer by
// continually halving the requested buffer size
while (!(x_size <= host->get_x_size() && y_size <= host->get_y_size())) {
x_size >>= 1;
y_size >>= 1;
}
if (x_size <= host->get_x_size() && y_size <= host->get_y_size()) {
buffer = engine->make_parasite(host, name, sort, x_size, y_size);
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_copy_texture);
buffer->add_render_texture(tex, to_ram ? RTM_copy_ram : RTM_bind_or_copy);
return buffer;
}
return NULL;
}
@ -1271,3 +1179,4 @@ do_determine_display_regions() {
stable_sort(_active_display_regions.begin(), _active_display_regions.end(), IndirectLess<DisplayRegion>());
}

View File

@ -61,8 +61,11 @@ class PNMImage;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsOutput : public TypedWritableReferenceCount, public DrawableRegion {
protected:
GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
GraphicsOutput(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
private:
GraphicsOutput(const GraphicsOutput &copy);
@ -221,6 +224,7 @@ protected:
};
PT(GraphicsStateGuardian) _gsg;
PT(GraphicsPipe) _pipe;
PT(GraphicsOutput) _host;
string _name;
pvector<RenderTexture> _textures;
bool _flip_ready;
@ -268,6 +272,7 @@ protected:
bool _display_regions_stale;
protected:
int _creation_flags;
int _x_size;
int _y_size;
bool _has_size;

View File

@ -186,25 +186,19 @@ close_gsg(GraphicsStateGuardian *gsg) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsPipe::make_window
// Function: GraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) GraphicsPipe::
make_window(GraphicsStateGuardian *, const string &) {
PT(GraphicsOutput) GraphicsPipe::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
display_cat.error()
<< get_type() << " cannot create onscreen windows.\n";
<< get_type() << " cannot create buffers or windows.\n";
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsPipe::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) GraphicsPipe::
make_buffer(GraphicsStateGuardian *, const string &, int, int) {
display_cat.error()
<< get_type() << " cannot create offscreen buffers.\n";
return NULL;
}

View File

@ -73,6 +73,44 @@ PUBLISHED:
OT_texture_buffer = 0x0008,
};
enum BufferCreationFlags {
// How many RGBA aux bitplanes do you need?
BF_need_aux_rgba_MASK = 0x00000003,
BF_need_0_aux_rgba = 0x00000000,
BF_need_1_aux_rgba = 0x00000001,
BF_need_2_aux_rgba = 0x00000002,
BF_need_3_aux_rgba = 0x00000003,
// How many half-float rgba aux bitplanes do you need?
// This is not currently implemented.
BF_need_aux_hrgba_MASK = 0x0000000C,
BF_need_0_aux_hrgba = 0x00000000,
BF_need_1_aux_hrgba = 0x00000004,
BF_need_2_aux_hrgba = 0x00000008,
BF_need_3_aux_hrgba = 0x0000000C,
// How many full-float single-channel bitplanes do you need?
// This is not currently implemented.
BF_need_aux_float_MASK = 0x00000030,
BF_need_0_aux_float = 0x00000000,
BF_need_1_aux_float = 0x00000010,
BF_need_2_aux_float = 0x00000020,
BF_need_3_aux_float = 0x00000040,
// Flags that control what type of output is returned.
BF_refuse_parasite = 0x00000100,
BF_require_parasite = 0x00000200,
BF_refuse_window = 0x00000400,
BF_require_window = 0x00000800,
// Miscellaneous control flags.
BF_can_bind_color = 0x00010000, // Need capability: bind the color bitplane to a tex.
BF_can_bind_every = 0x00020000, // Need capability: bind all bitplanes to a tex.
BF_size_track_host = 0x00040000, // Buffer should track the host size.
BF_no_new_gsg = 0x00080000, // Do not create a new gsg, no matter what.
};
INLINE bool is_valid() const;
INLINE int get_supported_types() const;
INLINE bool supports_type(int flags) const;
@ -90,18 +128,20 @@ public:
virtual PT(GraphicsDevice) make_device(void *scrn = NULL);
protected:
// The make_window() and make_gsg() interfaces on GraphicsPipe are
// The make_output() 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.
// the interface on GraphicsEngine to make a new window or buffer.
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);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size);
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
Mutex _lock;
bool _is_valid;

View File

@ -36,9 +36,12 @@ TypeHandle GraphicsWindow::_type_handle;
// GraphicsEngine::make_window() function.
////////////////////////////////////////////////////////////////////
GraphicsWindow::
GraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
GraphicsOutput(pipe, gsg, name)
GraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsOutput(pipe, name, x_size, y_size, flags, gsg, host)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
@ -46,14 +49,7 @@ GraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
if (display_cat.is_debug()) {
display_cat.debug()
<< "Creating new window " << get_name()
<< " using GSG " << (void *)gsg << "\n";
}
_red_blue_stereo = red_blue_stereo && !_gsg->get_properties().is_stereo();
if (_red_blue_stereo) {
_left_eye_color_mask = parse_color_mask(red_blue_stereo_colors.get_word(0));
_right_eye_color_mask = parse_color_mask(red_blue_stereo_colors.get_word(1));
<< "Creating new window " << get_name() << "\n";
}
_properties.set_open(false);
@ -770,3 +766,4 @@ parse_color_mask(const string &word) {
return result;
}

View File

@ -40,8 +40,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsWindow : public GraphicsOutput {
protected:
GraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
GraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
PUBLISHED:
virtual ~GraphicsWindow();

View File

@ -30,9 +30,9 @@ TypeHandle ParasiteBuffer::_type_handle;
////////////////////////////////////////////////////////////////////
ParasiteBuffer::
ParasiteBuffer(GraphicsOutput *host, const string &name,
int x_size, int y_size) :
GraphicsOutput(host->get_pipe(), host->get_gsg(), name),
_host(host)
int x_size, int y_size, int flags) :
GraphicsOutput(host->get_pipe(), name,
x_size, y_size, flags, host->get_gsg(), host)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
@ -44,12 +44,11 @@ ParasiteBuffer(GraphicsOutput *host, const string &name,
<< " on " << _host->get_name() << "\n";
}
if ((x_size == 0)&&(y_size == 0)) {
_track_host_size = true;
_creation_flags = flags;
if (flags & GraphicsPipe::BF_size_track_host) {
x_size = host->get_x_size();
y_size = host->get_y_size();
} else {
_track_host_size = false;
}
_x_size = x_size;
@ -113,14 +112,14 @@ begin_frame(FrameMode mode) {
return false;
}
if (_track_host_size) {
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
if ((_host->get_x_size() != _x_size)||
(_host->get_y_size() != _y_size)) {
set_size_and_recalc(_host->get_x_size(),
_host->get_y_size());
}
}
clear_cube_map_selection();
return true;
}
@ -145,6 +144,11 @@ end_frame(FrameMode mode) {
_host->end_frame(FM_parasite);
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;
}
}
copy_to_textures();
if (_one_shot) {
prepare_for_deletion();

View File

@ -55,7 +55,7 @@
class EXPCL_PANDA ParasiteBuffer : public GraphicsOutput {
public:
ParasiteBuffer(GraphicsOutput *host, const string &name,
int x_size, int y_size);
int x_size, int y_size, int flags);
PUBLISHED:
virtual ~ParasiteBuffer();
@ -68,8 +68,7 @@ public:
virtual GraphicsOutput *get_host();
private:
PT(GraphicsOutput) _host;
bool _track_host_size;
int _creation_flags;
public:
static TypeHandle get_class_type() {

View File

@ -41,10 +41,12 @@ TypeHandle wdxGraphicsBuffer8::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsBuffer8::
wdxGraphicsBuffer8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
wdxGraphicsBuffer8(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host):
GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
{
// initialize all class members
_cube_map_index = -1;

View File

@ -36,9 +36,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX wdxGraphicsBuffer8 : public GraphicsBuffer {
public:
wdxGraphicsBuffer8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size);
wdxGraphicsBuffer8(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wdxGraphicsBuffer8();
virtual bool begin_frame(FrameMode mode);

View File

@ -81,40 +81,65 @@ pipe_constructor() {
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe8::make_window
// Function: wdxGraphicsPipe8::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) wdxGraphicsPipe8::
make_window(GraphicsStateGuardian *gsg, const string &name) {
PT(GraphicsOutput) wdxGraphicsPipe8::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
if (!_is_valid) {
return NULL;
}
// thanks to the dumb threading requirements this constructor
// actually does nothing but create an empty c++ object. no windows
// are really opened until wdxGraphicsWindow8->open_window() is
// called
return new wdxGraphicsWindow8(this, gsg, name);
}
DXGraphicsStateGuardian8 *wdxgsg;
DCAST_INTO_R(wdxgsg, gsg, NULL);
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe8::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) wdxGraphicsPipe8::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
// First thing to try: a visible window.
// hmmmm must return NULL if render to texture is supported and you don't
// want to use it, otherwise it doesn't work
if (support_render_texture && gsg->get_supports_render_texture ( )) {
return new wdxGraphicsBuffer8(this, gsg, name, x_size, y_size);
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new wdxGraphicsWindow8(this, name, x_size, y_size, flags, gsg, host);
}
else {
return NULL;
// Second thing to try: a wdxGraphicsBuffer8
if (retry == 1) {
if ((!support_render_texture)||
((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
if (precertify) {
if (!gsg->get_supports_render_texture()) {
return NULL;
}
}
return new wdxGraphicsBuffer8(this, name, x_size, y_size, flags, gsg, host);
}
// Nothing else left to try.
return NULL;
}
////////////////////////////////////////////////////////////////////

View File

@ -58,9 +58,12 @@ public:
bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
protected:
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg, const string &name);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size);
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
private:
bool init();

View File

@ -39,9 +39,12 @@ TypeHandle wdxGraphicsWindow8::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsWindow8::
wdxGraphicsWindow8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
WinGraphicsWindow(pipe, gsg, name)
wdxGraphicsWindow8(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host):
WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
{
// dont actually create the window in the constructor. reason:
// multi-threading requires panda C++ window object to exist in

View File

@ -34,8 +34,11 @@ class wdxGraphicsPipe8;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX wdxGraphicsWindow8 : public WinGraphicsWindow {
public:
wdxGraphicsWindow8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
wdxGraphicsWindow8(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wdxGraphicsWindow8();
virtual bool begin_frame(FrameMode mode);

View File

@ -38,10 +38,12 @@ TypeHandle wdxGraphicsBuffer9::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsBuffer9::
wdxGraphicsBuffer9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
wdxGraphicsBuffer9(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host):
GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
{
// initialize all class members
_cube_map_index = -1;

View File

@ -36,9 +36,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX wdxGraphicsBuffer9 : public GraphicsBuffer {
public:
wdxGraphicsBuffer9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size);
wdxGraphicsBuffer9(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wdxGraphicsBuffer9();
virtual bool begin_frame(FrameMode mode);

View File

@ -81,39 +81,65 @@ pipe_constructor() {
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe9::make_window
// Function: wdxGraphicsPipe9::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) wdxGraphicsPipe9::
make_window(GraphicsStateGuardian *gsg, const string &name) {
PT(GraphicsOutput) wdxGraphicsPipe9::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
if (!_is_valid) {
return NULL;
}
// thanks to the dumb threading requirements this constructor
// actually does nothing but create an empty c++ object. no windows
// are really opened until wdxGraphicsWindow9->open_window() is
// called
return new wdxGraphicsWindow9(this, gsg, name);
}
DXGraphicsStateGuardian9 *wdxgsg;
DCAST_INTO_R(wdxgsg, gsg, NULL);
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe9::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) wdxGraphicsPipe9::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
// First thing to try: a visible window.
// if (support_render_texture && gsg->get_supports_render_texture ( )) {
return new wdxGraphicsBuffer9(this, gsg, name, x_size, y_size);
/* }
else {
return NULL;
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new wdxGraphicsWindow9(this, name, x_size, y_size, flags, gsg, host);
}
*/
// Second thing to try: a wdxGraphicsBuffer9
if (retry == 1) {
if ((!support_render_texture)||
((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
if (precertify) {
if (!gsg->get_supports_render_texture()) {
return NULL;
}
}
return new wdxGraphicsBuffer9(this, name, x_size, y_size, flags, gsg, host);
}
// Nothing else left to try.
return NULL;
}
////////////////////////////////////////////////////////////////////

View File

@ -58,9 +58,13 @@ public:
bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
protected:
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg, const string &name);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size);
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
private:
bool init();
bool find_all_card_memavails();

View File

@ -39,9 +39,12 @@ TypeHandle wdxGraphicsWindow9::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsWindow9::
wdxGraphicsWindow9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
WinGraphicsWindow(pipe, gsg, name)
wdxGraphicsWindow9(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host):
WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
{
// dont actually create the window in the constructor. reason:
// multi-threading requires panda C++ window object to exist in

View File

@ -34,8 +34,11 @@ class wdxGraphicsPipe9;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX wdxGraphicsWindow9 : public WinGraphicsWindow {
public:
wdxGraphicsWindow9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
wdxGraphicsWindow9(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wdxGraphicsWindow9();
virtual bool begin_frame(FrameMode mode);

View File

@ -37,10 +37,12 @@ TypeHandle glxGraphicsBuffer::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
glxGraphicsBuffer::
glxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
glxGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
{
glxGraphicsPipe *glx_pipe;
DCAST_INTO_V(glx_pipe, _pipe);

View File

@ -35,10 +35,11 @@
////////////////////////////////////////////////////////////////////
class glxGraphicsBuffer : public GraphicsBuffer {
public:
glxGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
glxGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size);
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~glxGraphicsBuffer();
virtual bool begin_frame(FrameMode mode);

View File

@ -269,38 +269,80 @@ make_gsg(const FrameBufferProperties &properties,
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsPipe::make_window
// Function: glxGraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) glxGraphicsPipe::
make_window(GraphicsStateGuardian *gsg, const string &name) {
PT(GraphicsOutput) glxGraphicsPipe::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
if (!_is_valid) {
return NULL;
}
return new glxGraphicsWindow(this, gsg, name);
}
glxGraphicsStateGuardian *glxgsg;
DCAST_INTO_R(glxgsg, gsg, NULL);
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsPipe::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) glxGraphicsPipe::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
if (!_is_valid) {
return NULL;
// First thing to try: a glxGraphicsWindow
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new glxGraphicsWindow(this, name, x_size, y_size, flags, gsg, host);
}
// // Second thing to try: a glGraphicsBuffer
//
// if (retry == 1) {
// if ((!support_render_texture)||
// ((flags&BF_require_parasite)!=0)||
// ((flags&BF_require_window)!=0)) {
// return NULL;
// }
// if (precertify) {
// if (!glxgsg->_supports_framebuffer_object) {
// return NULL;
// }
// }
// return new glGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
// }
#ifdef HAVE_GLXFBCONFIG
return new glxGraphicsBuffer(this, gsg, name, x_size, y_size);
#else
return NULL;
// Third thing to try: a glxGraphicsBuffer
if (retry == 2) {
if ((!support_render_texture)||
((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new glxGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
}
#endif // HAVE_GLXFBCONFIG
// Nothing else left to try.
return NULL;
}
#ifdef HAVE_GLXFBCONFIG
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsPipe::choose_fbconfig

View File

@ -113,11 +113,12 @@ public:
protected:
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,
const string &name,
int x_size, int y_size);
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
private:
#ifdef HAVE_GLXFBCONFIG

View File

@ -44,9 +44,12 @@ TypeHandle glxGraphicsWindow::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
glxGraphicsWindow::
glxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
GraphicsWindow(pipe, gsg, name)
glxGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
{
glxGraphicsPipe *glx_pipe;
DCAST_INTO_V(glx_pipe, _pipe);

View File

@ -32,8 +32,11 @@
////////////////////////////////////////////////////////////////////
class glxGraphicsWindow : public GraphicsWindow {
public:
glxGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
glxGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~glxGraphicsWindow();
virtual bool move_pointer(int device, int x, int y);

View File

@ -29,10 +29,12 @@ TypeHandle OsMesaGraphicsBuffer::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
OsMesaGraphicsBuffer::
OsMesaGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
OsMesaGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
{
_type = GL_UNSIGNED_BYTE;
}

View File

@ -32,10 +32,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAMESA OsMesaGraphicsBuffer : public GraphicsBuffer {
public:
OsMesaGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
OsMesaGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size);
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~OsMesaGraphicsBuffer();
virtual bool begin_frame(FrameMode mode);

View File

@ -119,12 +119,38 @@ make_gsg(const FrameBufferProperties &properties,
}
////////////////////////////////////////////////////////////////////
// Function: OsMesaGraphicsPipe::make_buffer
// Function: OsMesaGraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) OsMesaGraphicsPipe::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
return new OsMesaGraphicsBuffer(this, gsg, name, x_size, y_size);
PT(GraphicsOutput) OsMesaGraphicsPipe::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
if (!_is_valid) {
return NULL;
}
// First thing to try: an OsMesaGraphicsBuffer
if (retry == 0) {
if ((!support_render_texture)||
((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new OsMesaGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
}
// Nothing else left to try.
return NULL;
}

View File

@ -48,9 +48,12 @@ public:
protected:
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);
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
private:

View File

@ -33,10 +33,12 @@ TypeHandle wglGraphicsBuffer::_type_handle;
// Description:
////////////////////////////////////////////////////////////////////
wglGraphicsBuffer::
wglGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
wglGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
{
_pbuffer = (HPBUFFERARB)0;
_pbuffer_dc = (HDC)0;

View File

@ -41,9 +41,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAGL wglGraphicsBuffer : public GraphicsBuffer {
public:
wglGraphicsBuffer(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
wglGraphicsBuffer(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size);
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wglGraphicsBuffer();
virtual bool begin_frame(FrameMode mode);

View File

@ -73,7 +73,7 @@ pipe_constructor() {
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::make_gsg
// Access: Protected, Virtual
// Access: Private
// Description: Creates a new GSG to use the pipe (but no windows
// have been created yet for the GSG). This method will
// be called in the draw thread for the GSG.
@ -190,25 +190,83 @@ make_gsg(const FrameBufferProperties &properties,
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::make_window
// Function: wglGraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
// Description: Creates a new window or buffer on the pipe, if possible.
// This routine is only called from GraphicsEngine::make_output.
////////////////////////////////////////////////////////////////////
PT(GraphicsWindow) wglGraphicsPipe::
make_window(GraphicsStateGuardian *gsg, const string &name) {
return new wglGraphicsWindow(this, gsg, name);
PT(GraphicsOutput) wglGraphicsPipe::
make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify) {
if (!_is_valid) {
return NULL;
}
wglGraphicsStateGuardian *wglgsg;
DCAST_INTO_R(wglgsg, gsg, NULL);
// First thing to try: a wglGraphicsWindow
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new wglGraphicsWindow(this, name, x_size, y_size, flags, gsg, host);
}
// // Second thing to try: a glGraphicsBuffer
//
// if (retry == 1) {
// if ((!support_render_texture)||
// ((flags&BF_require_parasite)!=0)||
// ((flags&BF_require_window)!=0)) {
// return NULL;
// }
// if (precertify) {
// if (!wglgsg->_supports_framebuffer_object) {
// return NULL;
// }
// }
// return new glGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
// }
// Third thing to try: a wglGraphicsBuffer
if (retry == 2) {
if ((!support_render_texture)||
((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)||
((flags&BF_need_aux_rgba_MASK)!=0)||
((flags&BF_need_aux_hrgba_MASK)!=0)||
((flags&BF_need_aux_float_MASK)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
if (precertify) {
if (!wglgsg->_supports_pbuffer) {
return NULL;
}
}
return new wglGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
}
// Nothing else left to try.
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) wglGraphicsPipe::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
return new wglGraphicsBuffer(this, gsg, name, x_size, y_size);
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsPipe::choose_pfnum

View File

@ -39,14 +39,17 @@ public:
static PT(GraphicsPipe) pipe_constructor();
protected:
virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
virtual PT(GraphicsOutput) make_output(const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool precertify);
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,
const string &name,
int x_size, int y_size);
private:
static int choose_pfnum(const FrameBufferProperties &properties, HDC hdc);
static int try_for_pfnum(HDC hdc, bool hardware, bool software,
int frame_buffer_mode,
@ -88,6 +91,7 @@ private:
static TypeHandle _type_handle;
friend class wglGraphicsBuffer;
friend class wglGraphicsWindow;
};
#include "wglGraphicsPipe.I"

View File

@ -131,9 +131,12 @@ GetAvailVidMem() {
// Description:
////////////////////////////////////////////////////////////////////
wglGraphicsWindow::
wglGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
WinGraphicsWindow(pipe, gsg, name)
wglGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
{
_hdc = (HDC)0;
}

View File

@ -29,8 +29,11 @@
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAGL wglGraphicsWindow : public WinGraphicsWindow {
public:
wglGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
wglGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~wglGraphicsWindow();
virtual bool begin_frame(FrameMode mode);

View File

@ -80,9 +80,12 @@ static tRegisterRawInputDevices pRegisterRawInputDevices;
// Description:
////////////////////////////////////////////////////////////////////
WinGraphicsWindow::
WinGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name) :
GraphicsWindow(pipe, gsg, name)
WinGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host) :
GraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
{
initialize_input_devices();
_hWnd = (HWND)0;

View File

@ -41,8 +41,11 @@ class WinGraphicsPipe;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAWIN WinGraphicsWindow : public GraphicsWindow {
public:
WinGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name);
WinGraphicsWindow(GraphicsPipe *pipe,
const string &name,
int x_size, int y_size, int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~WinGraphicsWindow();
virtual bool move_pointer(int device, int x, int y);