open_toontown_panda3d/panda/src/display/graphicsEngine.h

271 lines
8.8 KiB
C++

// Filename: graphicsEngine.h
// Created by: drose (24Feb02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef GRAPHICSENGINE_H
#define GRAPHICSENGINE_H
#include "pandabase.h"
#include "graphicsWindow.h"
#include "graphicsBuffer.h"
#include "frameBufferProperties.h"
#include "graphicsThreadingModel.h"
#include "sceneSetup.h"
#include "pointerTo.h"
#include "thread.h"
#include "pmutex.h"
#include "conditionVar.h"
#include "pStatCollector.h"
#include "pset.h"
#include "ordered_vector.h"
#include "indirectLess.h"
class Pipeline;
class DisplayRegion;
class GraphicsPipe;
class FrameBufferProperties;
class Texture;
////////////////////////////////////////////////////////////////////
// Class : GraphicsEngine
// Description : This class is the main interface to controlling the
// render process. There is typically only one
// GraphicsEngine in an application, and it synchronizes
// rendering to all all of the active windows; although
// it is possible to have multiple GraphicsEngine
// objects if multiple synchronicity groups are
// required.
//
// The GraphicsEngine is responsible for managing the
// various cull and draw threads. The application
// simply calls engine->render_frame() and considers it
// done.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GraphicsEngine {
PUBLISHED:
GraphicsEngine(Pipeline *pipeline = NULL);
~GraphicsEngine();
void set_frame_buffer_properties(const FrameBufferProperties &properties);
FrameBufferProperties get_frame_buffer_properties() const;
void set_threading_model(const GraphicsThreadingModel &threading_model);
GraphicsThreadingModel get_threading_model() const;
INLINE void set_auto_flip(bool auto_flip);
INLINE bool get_auto_flip() const;
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);
bool remove_window(GraphicsOutput *window);
void remove_all_windows();
void reset_all_windows(bool swapchain);
bool is_empty() const;
int get_num_windows() const;
GraphicsOutput *get_window(int n) const;
void render_frame();
void open_windows();
void sync_frame();
void flip_frame();
void render_subframe(GraphicsOutput *win, DisplayRegion *dr,
bool cull_sorting);
public:
enum ThreadState {
TS_wait,
TS_do_frame,
TS_do_flip,
TS_do_release,
TS_do_windows,
TS_terminate,
TS_done
};
enum CallbackTime {
CB_pre_frame,
CB_post_frame,
CB_len // Not an option; just indicates the size of the list.
};
typedef void CallbackFunction(void *data);
bool add_callback(const string &thread_name, CallbackTime callback_time,
CallbackFunction *func, void *data);
bool remove_callback(const string &thread_name, CallbackTime callback_time,
CallbackFunction *func, void *data);
private:
class Callback {
public:
INLINE Callback(CallbackFunction *func, void *data);
INLINE bool operator < (const Callback &other) const;
INLINE void do_callback() const;
private:
CallbackFunction *_func;
void *_data;
};
typedef ov_set< PT(GraphicsOutput), IndirectLess<GraphicsOutput> > Windows;
typedef pset< PT(GraphicsStateGuardian) > GSGs;
typedef pset< Callback > Callbacks;
void set_window_sort(GraphicsOutput *window, int sort);
void cull_and_draw_together(const Windows &wlist);
void cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr);
void cull_bin_draw(const Windows &wlist);
void cull_bin_draw(GraphicsOutput *win, DisplayRegion *dr);
void make_contexts(const Windows &wlist);
void process_events(const Windows &wlist);
void flip_windows(const Windows &wlist);
void do_sync_frame();
void do_flip_frame();
INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg);
PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg, DisplayRegion *dr);
void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
GraphicsStateGuardian *gsg);
void do_draw(CullResult *cull_result, SceneSetup *scene_setup,
GraphicsOutput *win, DisplayRegion *dr);
bool setup_gsg(GraphicsStateGuardian *gsg, SceneSetup *scene_setup);
void do_add_window(GraphicsOutput *window, GraphicsStateGuardian *gsg,
const GraphicsThreadingModel &threading_model);
void do_remove_window(GraphicsOutput *window);
void do_resort_windows();
void terminate_threads();
static const RenderState *get_invert_polygon_state();
// The WindowRenderer class records the stages of the pipeline that
// each thread (including the main thread, a.k.a. "app") should
// process, and the list of windows for each stage.
class WindowRenderer {
public:
void add_gsg(GraphicsStateGuardian *gsg);
void add_window(Windows &wlist, GraphicsOutput *window);
void remove_window(GraphicsOutput *window);
void resort_windows();
void do_frame(GraphicsEngine *engine);
void do_windows(GraphicsEngine *engine);
void do_flip(GraphicsEngine *engine);
void do_release(GraphicsEngine *engine);
void do_close(GraphicsEngine *engine);
void do_pending(GraphicsEngine *engine);
bool any_done_gsgs() const;
bool add_callback(CallbackTime callback_time, const Callback &callback);
bool remove_callback(CallbackTime callback_time, const Callback &callback);
private:
void do_callbacks(CallbackTime callback_time);
public:
Windows _cull; // cull stage
Windows _cdraw; // cull-and-draw-together stage
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.
GSGs _gsgs; // draw stage
Callbacks _callbacks[CB_len];
Mutex _wl_lock;
};
class RenderThread : public Thread, public WindowRenderer {
public:
RenderThread(const string &name, GraphicsEngine *engine);
virtual void thread_main();
GraphicsEngine *_engine;
Mutex _cv_mutex;
ConditionVar _cv_start;
ConditionVar _cv_done;
ThreadState _thread_state;
};
WindowRenderer *get_window_renderer(const string &name);
Pipeline *_pipeline;
Windows _windows;
bool _windows_sorted;
unsigned int _window_sort_index;
WindowRenderer _app;
typedef pmap<string, PT(RenderThread) > Threads;
Threads _threads;
FrameBufferProperties _frame_buffer_properties;
GraphicsThreadingModel _threading_model;
bool _auto_flip;
bool _portal_enabled; //toggle to portal culling on/off
enum FlipState {
FS_draw, // Still drawing.
FS_sync, // All windows are done drawing.
FS_flip, // All windows are done drawing and have flipped.
};
FlipState _flip_state;
Mutex _lock;
static PStatCollector _wait_pcollector;
static PStatCollector _cycle_pcollector;
static PStatCollector _app_pcollector;
static PStatCollector _yield_pcollector;
static PStatCollector _cull_pcollector;
static PStatCollector _draw_pcollector;
static PStatCollector _sync_pcollector;
static PStatCollector _flip_pcollector;
static PStatCollector _flip_begin_pcollector;
static PStatCollector _flip_end_pcollector;
static PStatCollector _transform_states_pcollector;
static PStatCollector _transform_states_unused_pcollector;
static PStatCollector _render_states_pcollector;
static PStatCollector _render_states_unused_pcollector;
friend class WindowRenderer;
friend class GraphicsOutput;
};
#include "graphicsEngine.I"
#endif