diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 849e9efb4f..6ff2f0f78d 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -476,6 +476,42 @@ make_output(GraphicsPipe *pipe, return NULL; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsEngine::add_window +// Access: Published +// Description: This can be used to add a newly-created +// GraphicsOutput object (and its GSG) to the engine's +// list of windows, and requests that it be opened. +// This shouldn't be called by user code as +// make_output normally does this under the hood; it +// may be useful in esoteric cases in which a custom +// window object is used. +//////////////////////////////////////////////////////////////////// +bool GraphicsEngine:: +add_window(GraphicsOutput *window, int sort) { + nassertr(window != NULL, false); + + GraphicsThreadingModel threading_model = get_threading_model(); + nassertr(this == window->get_engine(), false); + + window->_sort = sort; + do_add_window(window, threading_model); + + open_windows(); + if (window->is_valid()) { + do_add_gsg(window->get_gsg(), window->get_pipe(), threading_model); + + display_cat.info() + << "Added output of type " << window->get_type() << "\n"; + + return true; + + } else { + remove_window(window); + return false; + } +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsEngine::remove_window // Access: Published @@ -2107,6 +2143,8 @@ do_add_window(GraphicsOutput *window, void GraphicsEngine:: do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe, const GraphicsThreadingModel &threading_model) { + nassertv(gsg != NULL); + ReMutexHolder holder(_lock); nassertv(gsg->get_pipe() == pipe && gsg->get_engine() == this); gsg->_threading_model = threading_model; diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 7933f73350..cb371076ee 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -80,7 +80,7 @@ PUBLISHED: const WindowProperties &win_prop, int flags, GraphicsStateGuardian *gsg = NULL, GraphicsOutput *host = NULL); - + // Syntactic shorthand versions of make_output INLINE GraphicsOutput *make_buffer(GraphicsOutput *host, const string &name, int sort, @@ -91,7 +91,8 @@ PUBLISHED: INLINE GraphicsOutput *make_parasite(GraphicsOutput *host, const string &name, int sort, int x_size, int y_size); - + + bool add_window(GraphicsOutput *window, int sort); bool remove_window(GraphicsOutput *window); void remove_all_windows(); void reset_all_windows(bool swapchain); @@ -104,7 +105,7 @@ PUBLISHED: BLOCKING void render_frame(); BLOCKING void open_windows(); BLOCKING void sync_frame(); - BLOCKING void ready_flip(); + BLOCKING void ready_flip(); BLOCKING void flip_frame(); bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg); @@ -130,7 +131,7 @@ public: public: static void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, GraphicsStateGuardian *gsg, Thread *current_thread); - + private: typedef ov_set< PT(GraphicsOutput), IndirectLess > Windows; typedef pset< PT(GraphicsStateGuardian) > GSGs; @@ -158,7 +159,7 @@ private: void do_flip_frame(Thread *current_thread); INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg); - PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, + PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr); void do_draw(CullResult *cull_result, SceneSetup *scene_setup, GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread); @@ -281,7 +282,7 @@ private: Windows _cull; // cull stage Windows _cdraw; // cull-and-draw-together stage Windows _draw; // draw stage - Windows _window; // window stage, i.e. process windowing events + Windows _window; // window stage, i.e. process windowing events // These are not kept sorted. Windows _pending_close; // moved from _window, pending close. diff --git a/panda/src/display/graphicsPipe.cxx b/panda/src/display/graphicsPipe.cxx index 76ed9f2135..4865e3da9f 100644 --- a/panda/src/display/graphicsPipe.cxx +++ b/panda/src/display/graphicsPipe.cxx @@ -82,11 +82,25 @@ GraphicsPipe:: // performed: typically either the app thread (e.g. X) // or the draw thread (Windows). //////////////////////////////////////////////////////////////////// -GraphicsPipe::PreferredWindowThread +GraphicsPipe::PreferredWindowThread GraphicsPipe::get_preferred_window_thread() const { return PWT_draw; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsPipe::make_callback_gsg +// Access: Public, Virtual +// Description: This is called when make_output() is used to create a +// CallbackGraphicsWindow. If the GraphicsPipe can +// construct a GSG that's not associated with any +// particular window object, do so now, assuming the +// correct graphics context has been set up externally. +//////////////////////////////////////////////////////////////////// +PT(GraphicsStateGuardian) GraphicsPipe:: +make_callback_gsg(GraphicsEngine *engine) { + return NULL; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::make_device // Access: Public, Virtual @@ -95,7 +109,7 @@ GraphicsPipe::get_preferred_window_thread() const { //////////////////////////////////////////////////////////////////// PT(GraphicsDevice) GraphicsPipe:: make_device(void *scrn) { - display_cat.error() + display_cat.error() << "make_device() unimplemented by " << get_type() << "\n"; return NULL; } @@ -138,20 +152,6 @@ make_output(const string &name, return NULL; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsPipe::make_callback_gsg -// Access: Protected, Virtual -// Description: This is called when make_output() is used to create a -// CallbackGraphicsWindow. If the GraphicsPipe can -// construct a GSG that's not associated with any -// particular window object, do so now, assuming the -// correct graphics context has been set up externally. -//////////////////////////////////////////////////////////////////// -PT(GraphicsStateGuardian) GraphicsPipe:: -make_callback_gsg(GraphicsEngine *engine) { - return NULL; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsPipe::get_display_information // Access: Published diff --git a/panda/src/display/graphicsPipe.h b/panda/src/display/graphicsPipe.h index 998a81ace1..134a3baddd 100644 --- a/panda/src/display/graphicsPipe.h +++ b/panda/src/display/graphicsPipe.h @@ -101,7 +101,7 @@ PUBLISHED: DisplayInformation *get_display_information(); virtual void lookup_cpu_data(); - + virtual string get_interface_name() const=0; public: @@ -114,9 +114,11 @@ public: INLINE GraphicsDevice *get_device() const; virtual PT(GraphicsDevice) make_device(void *scrn = NULL); + virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine); + protected: virtual void close_gsg(GraphicsStateGuardian *gsg); - + virtual PT(GraphicsOutput) make_output(const string &name, const FrameBufferProperties &fb_prop, const WindowProperties &win_prop, @@ -126,8 +128,7 @@ protected: GraphicsOutput *host, int retry, bool &precertify); - virtual PT(GraphicsStateGuardian) make_callback_gsg(GraphicsEngine *engine); - + LightMutex _lock; bool _is_valid; @@ -135,7 +136,7 @@ protected: int _display_width; int _display_height; PT(GraphicsDevice) _device; - + DisplayInformation *_display_information; static const int strip_properties[];