diff --git a/panda/src/display/graphicsBuffer.cxx b/panda/src/display/graphicsBuffer.cxx index 8f7aff6019..1395d87d0e 100644 --- a/panda/src/display/graphicsBuffer.cxx +++ b/panda/src/display/graphicsBuffer.cxx @@ -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; } diff --git a/panda/src/display/graphicsBuffer.h b/panda/src/display/graphicsBuffer.h index 49ca35327d..1c7390ac35 100644 --- a/panda/src/display/graphicsBuffer.h +++ b/panda/src/display/graphicsBuffer.h @@ -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(); diff --git a/panda/src/display/graphicsEngine.I b/panda/src/display/graphicsEngine.I index c54be03233..fdb381e36e 100644 --- a/panda/src/display/graphicsEngine.I +++ b/panda/src/display/graphicsEngine.I @@ -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); } + diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 8952b6f27a..36529cd565 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -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 diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index d471aba9d5..b039b524f1 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -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 diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index f5822789ca..3be8ef5b19 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -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()); } + diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 6a480515bb..791762fb32 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -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 ©); @@ -221,6 +224,7 @@ protected: }; PT(GraphicsStateGuardian) _gsg; PT(GraphicsPipe) _pipe; + PT(GraphicsOutput) _host; string _name; pvector _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; diff --git a/panda/src/display/graphicsPipe.cxx b/panda/src/display/graphicsPipe.cxx index 1eddb5b1ee..c200c8b3ae 100644 --- a/panda/src/display/graphicsPipe.cxx +++ b/panda/src/display/graphicsPipe.cxx @@ -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; -} diff --git a/panda/src/display/graphicsPipe.h b/panda/src/display/graphicsPipe.h index b26c8af73a..8b8a90458e 100644 --- a/panda/src/display/graphicsPipe.h +++ b/panda/src/display/graphicsPipe.h @@ -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; diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 8174cdbe8a..cb8bad3de7 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -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; } + diff --git a/panda/src/display/graphicsWindow.h b/panda/src/display/graphicsWindow.h index 9bbd1f3b22..90b5cf04e3 100644 --- a/panda/src/display/graphicsWindow.h +++ b/panda/src/display/graphicsWindow.h @@ -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(); diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx index 0cf20e7ad1..286082ce29 100644 --- a/panda/src/display/parasiteBuffer.cxx +++ b/panda/src/display/parasiteBuffer.cxx @@ -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; iopen_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; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/wdxGraphicsPipe8.h b/panda/src/dxgsg8/wdxGraphicsPipe8.h index 0344ed52ed..78aacd1d99 100644 --- a/panda/src/dxgsg8/wdxGraphicsPipe8.h +++ b/panda/src/dxgsg8/wdxGraphicsPipe8.h @@ -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(); diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index f28ffc4177..6802482579 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -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 diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.h b/panda/src/dxgsg8/wdxGraphicsWindow8.h index 957e1453fd..c8a304fa2b 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.h +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.h @@ -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); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index b14dbb1998..1fd079aa63 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -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; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.h b/panda/src/dxgsg9/wdxGraphicsBuffer9.h index a94607471a..c0fcc939db 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.h +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.h @@ -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); diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index c82a7b041a..b0b401842c 100755 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -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; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.h b/panda/src/dxgsg9/wdxGraphicsPipe9.h index 88802c66ff..74e717852f 100755 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.h +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.h @@ -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(); diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index a2dc6189d4..3399186664 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -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 diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.h b/panda/src/dxgsg9/wdxGraphicsWindow9.h index dccf79a448..73a28da460 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.h +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.h @@ -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); diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.cxx b/panda/src/glxdisplay/glxGraphicsBuffer.cxx index e9d887520b..06da69567a 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.cxx +++ b/panda/src/glxdisplay/glxGraphicsBuffer.cxx @@ -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); diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.h b/panda/src/glxdisplay/glxGraphicsBuffer.h index f5e3091803..6112f8736a 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.h +++ b/panda/src/glxdisplay/glxGraphicsBuffer.h @@ -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); diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index 434af14e93..95f4e6cce0 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/panda/src/glxdisplay/glxGraphicsPipe.cxx @@ -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 diff --git a/panda/src/glxdisplay/glxGraphicsPipe.h b/panda/src/glxdisplay/glxGraphicsPipe.h index b522b863bf..4365a57005 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.h +++ b/panda/src/glxdisplay/glxGraphicsPipe.h @@ -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 diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 81ad460e46..a827fe9567 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -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); diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index 286ddbe611..53eafb1145 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -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); diff --git a/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx b/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx index 10ce44518b..ad1bc52349 100644 --- a/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx +++ b/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx @@ -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; } diff --git a/panda/src/mesadisplay/osMesaGraphicsBuffer.h b/panda/src/mesadisplay/osMesaGraphicsBuffer.h index c8b9f3509c..3aea2bde2b 100644 --- a/panda/src/mesadisplay/osMesaGraphicsBuffer.h +++ b/panda/src/mesadisplay/osMesaGraphicsBuffer.h @@ -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); diff --git a/panda/src/mesadisplay/osMesaGraphicsPipe.cxx b/panda/src/mesadisplay/osMesaGraphicsPipe.cxx index fa27b42db9..8eb14dffbb 100644 --- a/panda/src/mesadisplay/osMesaGraphicsPipe.cxx +++ b/panda/src/mesadisplay/osMesaGraphicsPipe.cxx @@ -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; } diff --git a/panda/src/mesadisplay/osMesaGraphicsPipe.h b/panda/src/mesadisplay/osMesaGraphicsPipe.h index fb2123a526..70e70b1b9e 100644 --- a/panda/src/mesadisplay/osMesaGraphicsPipe.h +++ b/panda/src/mesadisplay/osMesaGraphicsPipe.h @@ -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: diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 7531d0d40c..1f49638b63 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -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; diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index 764dabfa2a..00300f34b3 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.h +++ b/panda/src/wgldisplay/wglGraphicsBuffer.h @@ -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); diff --git a/panda/src/wgldisplay/wglGraphicsPipe.cxx b/panda/src/wgldisplay/wglGraphicsPipe.cxx index 6cd7ad12ab..aa7d530931 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.cxx +++ b/panda/src/wgldisplay/wglGraphicsPipe.cxx @@ -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 diff --git a/panda/src/wgldisplay/wglGraphicsPipe.h b/panda/src/wgldisplay/wglGraphicsPipe.h index f04971cfe1..4195a4c5f1 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.h +++ b/panda/src/wgldisplay/wglGraphicsPipe.h @@ -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" diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 348b4bc7a2..e9c417890c 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -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; } diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index 5141c49af5..ccbe153759 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -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); diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index 0d76556bbd..2344f42bb9 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -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; diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index 529c007a45..1b99c1ec97 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -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);