First step in refactoring begin_frame and end_frame

This commit is contained in:
Josh Yelon 2006-02-03 21:18:42 +00:00
parent e62e3b1853
commit 4477cdbafb
23 changed files with 519 additions and 102 deletions

View File

@ -426,3 +426,55 @@ INLINE void GraphicsOutput::
win_display_regions_changed() {
_display_regions_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::begin_frame_spam
// Access: Public
// Description: Display the spam message associated with begin_frame
////////////////////////////////////////////////////////////////////
INLINE void GraphicsOutput::
begin_frame_spam() {
if (display_cat.is_spam()) {
display_cat.spam()
<< "begin_frame(): " << get_type() << " "
<< get_name() << " " << (void *)this << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::end_frame_spam
// Access: Public
// Description: Display the spam message associated with end_frame
////////////////////////////////////////////////////////////////////
INLINE void GraphicsOutput::
end_frame_spam() {
if (display_cat.is_spam()) {
display_cat.spam()
<< "end_frame(): " << get_type() << " "
<< get_name() << " " << (void *)this << "\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::clear_cube_map_selection
// Access: Public
// Description: Clear the variables that select a cube-map face.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsOutput::
clear_cube_map_selection() {
_cube_map_index = -1;
_cube_map_dr = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::trigger_flip
// Access: Public
// Description: Set the flip_ready flag, only if legal to do so.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsOutput::
trigger_flip() {
if (!_gsg->get_properties().is_single_buffered()) {
_flip_ready = true;
}
}

View File

@ -962,34 +962,53 @@ reset_window(bool swapchain) {
////////////////////////////////////////////////////////////////////
bool GraphicsOutput::
begin_frame() {
if (display_cat.is_spam()) {
display_cat.spam()
<< "begin_frame(): " << get_type() << " "
<< get_name() << " " << (void *)this << "\n";
}
return false;
}
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
end_frame() {
}
// Track the size of some other graphics output, if desired.
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::prepare_for_deletion
// Access: Protected
// Description: Set the delete flag, and do the usual cleanup
// activities associated with that.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
prepare_for_deletion() {
// But when show-buffers mode is enabled, we want to keep the
// window around until the user has a chance to see the texture.
// So we don't do most of the following in show-buffers mode.
if (!show_buffers) {
_active = false;
_delete_flag = true;
// We have to be sure to remove all of the display regions
// immediately, so that circular reference counts can be cleared
// up (each display region keeps a pointer to a CullResult,
// which can hold all sorts of pointers).
remove_all_display_regions();
// If we were rendering directly to texture, we can't delete the
// buffer until the texture is gone too.
for (int i=0; i<count_textures(); i++) {
if (get_rtm_mode(i) == RTM_bind_or_copy) {
_hold_textures.push_back(get_texture(i));
}
}
}
// Okay, we already have a GSG, so activate it.
make_current();
begin_render_texture();
_cube_map_index = -1;
_cube_map_dr = NULL;
return _gsg->begin_frame();
// We have to be sure to clear the _textures pointers, though, or
// we'll end up holding a reference to the textures forever.
clear_render_textures();
}
////////////////////////////////////////////////////////////////////
@ -1020,27 +1039,14 @@ clear() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
// Function: GraphicsOutput::copy_to_textures
// Access: Protected
// Description: For all textures marked RTM_copy_texture,
// RTM_copy_ram, RTM_triggered_copy_texture, or
// RTM_triggered_copy_ram, do the necessary copies.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
end_frame() {
if (display_cat.is_spam()) {
display_cat.spam()
<< "end_frame(): " << get_type() << " "
<< get_name() << " " << (void *)this << "\n";
}
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
// Handle all render-to-texture operations that use bind-to-texture
end_render_texture();
// Handle all render-to-texture operations that use copy-to-texture
copy_to_textures() {
for (int i=0; i<count_textures(); i++) {
RenderTextureMode rtm_mode = get_rtm_mode(i);
if ((rtm_mode == RTM_none)||(rtm_mode == RTM_bind_or_copy)) {
@ -1082,44 +1088,6 @@ end_frame() {
}
}
_trigger_copy = false;
// If we're not single-buffered, we're now ready to flip.
if (!_gsg->get_properties().is_single_buffered()) {
_flip_ready = true;
}
// In one-shot mode, we request the GraphicsEngine to delete the
// window after we have rendered a frame.
if (_one_shot) {
// But when show-buffers mode is enabled, we want to keep the
// window around until the user has a chance to see the texture.
// So we don't do most of the following in show-buffers mode.
if (!show_buffers) {
_active = false;
_delete_flag = true;
// We have to be sure to remove all of the display regions
// immediately, so that circular reference counts can be cleared
// up (each display region keeps a pointer to a CullResult,
// which can hold all sorts of pointers).
remove_all_display_regions();
// If we were rendering directly to texture, we can't delete the
// buffer until the texture is gone too.
for (int i=0; i<count_textures(); i++) {
if (get_rtm_mode(i) == RTM_bind_or_copy) {
_hold_textures.push_back(get_texture(i));
}
}
}
// We have to be sure to clear the _textures pointers, though, or
// we'll end up holding a reference to the textures forever.
clear_render_textures();
}
_cube_map_index = -1;
_cube_map_dr = NULL;
}
////////////////////////////////////////////////////////////////////

View File

@ -185,7 +185,17 @@ public:
// thread other than the window thread. These methods are normally
// called by the GraphicsEngine.
virtual void process_events();
protected:
void prepare_for_deletion();
void copy_to_textures();
INLINE void begin_frame_spam();
INLINE void end_frame_spam();
INLINE void clear_cube_map_selection();
INLINE void trigger_flip();
protected:
class RenderTexture {

View File

@ -96,6 +96,54 @@ get_host() {
return _host;
}
////////////////////////////////////////////////////////////////////
// Function: ParasiteBuffer::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
// should do whatever setup is required, and return true
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool ParasiteBuffer::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: ParasiteBuffer::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void ParasiteBuffer::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: ParasiteBuffer::make_current
// Access: Public, Virtual

View File

@ -63,10 +63,12 @@ PUBLISHED:
virtual bool is_active() const;
public:
virtual bool begin_frame();
virtual void end_frame();
virtual GraphicsOutput *get_host();
virtual void make_current();
virtual void auto_resize();
private:
PT(GraphicsOutput) _host;
bool _track_host_size;

View File

@ -81,14 +81,41 @@ wdxGraphicsBuffer8::
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer8::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_R(dxgsg, _gsg, false);
return GraphicsBuffer::begin_frame();
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////

View File

@ -42,6 +42,7 @@ public:
virtual ~wdxGraphicsBuffer8();
virtual bool begin_frame();
virtual void end_frame();
virtual void select_cube_map(int cube_map_index);
virtual void make_current();

View File

@ -100,6 +100,10 @@ make_current() {
////////////////////////////////////////////////////////////////////
bool wdxGraphicsWindow8::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
if (_awaiting_restore) {
// The fullscreen window was recently restored; we can't continue
// until the GSG says we can.
@ -111,12 +115,41 @@ begin_frame() {
init_resized_window();
}
bool return_val = WinGraphicsWindow::begin_frame();
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
bool return_val = _gsg->begin_frame();
_dxgsg->set_render_target();
return return_val;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsWindow8::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow8::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsWindow8::end_flip
// Access: Public, Virtual

View File

@ -38,9 +38,9 @@ public:
const string &name);
virtual ~wdxGraphicsWindow8();
virtual void make_current();
virtual bool begin_frame();
virtual void end_frame();
virtual void make_current();
virtual void end_flip();
virtual int verify_window_sizes(int numsizes, int *dimen);

View File

@ -78,16 +78,42 @@ wdxGraphicsBuffer9::
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer9::
begin_frame() {
DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E
DXGraphicsStateGuardian9 *dxgsg;
DCAST_INTO_R(dxgsg, _gsg, false);
return GraphicsBuffer::begin_frame();
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////

View File

@ -42,6 +42,7 @@ public:
virtual ~wdxGraphicsBuffer9();
virtual bool begin_frame();
virtual void end_frame();
virtual void select_cube_map(int cube_map_index);
virtual void make_current();

View File

@ -100,6 +100,10 @@ make_current() {
////////////////////////////////////////////////////////////////////
bool wdxGraphicsWindow9::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
if (_awaiting_restore) {
// The fullscreen window was recently restored; we can't continue
// until the GSG says we can.
@ -111,12 +115,41 @@ begin_frame() {
init_resized_window();
}
bool return_val = WinGraphicsWindow::begin_frame();
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
bool return_val = _gsg->begin_frame();
_dxgsg->set_render_target();
return return_val;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsWindow9::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow9::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsWindow9::end_flip
// Access: Public, Virtual

View File

@ -41,6 +41,7 @@ public:
virtual void make_current();
virtual bool begin_frame();
virtual void end_frame();
virtual void end_flip();
virtual int verify_window_sizes(int numsizes, int *dimen);
@ -105,4 +106,4 @@ private:
#include "wdxGraphicsWindow9.I"
#endif
#endif

View File

@ -62,6 +62,54 @@ glxGraphicsBuffer::
nassertv(_pbuffer == None);
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsBuffer::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
// should do whatever setup is required, and return true
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool glxGraphicsBuffer::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsBuffer::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void glxGraphicsBuffer::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsBuffer::make_current
// Access: Public, Virtual

View File

@ -41,6 +41,8 @@ public:
virtual ~glxGraphicsBuffer();
virtual bool begin_frame();
virtual void end_frame();
virtual void make_current();
virtual void release_gsg();

View File

@ -171,13 +171,46 @@ release_gsg() {
////////////////////////////////////////////////////////////////////
bool glxGraphicsWindow::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
if (_awaiting_configure) {
// Don't attempt to draw while we have just reconfigured the
// window and we haven't got the notification back yet.
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
return GraphicsWindow::begin_frame();
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsWindow::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void glxGraphicsWindow::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////

View File

@ -43,6 +43,7 @@ public:
virtual void release_gsg();
virtual bool begin_frame();
virtual void end_frame();
virtual void begin_flip();
virtual void process_events();

View File

@ -46,6 +46,54 @@ OsMesaGraphicsBuffer::
~OsMesaGraphicsBuffer() {
}
////////////////////////////////////////////////////////////////////
// Function: OsMesaGraphicsBuffer::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
// should do whatever setup is required, and return true
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool OsMesaGraphicsBuffer::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: OsMesaGraphicsBuffer::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void OsMesaGraphicsBuffer::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: OsMesaGraphicsBuffer::make_current
// Access: Public, Virtual

View File

@ -38,6 +38,8 @@ public:
virtual ~OsMesaGraphicsBuffer();
virtual bool begin_frame();
virtual void end_frame();
virtual void make_current();
protected:

View File

@ -66,6 +66,7 @@ wglGraphicsBuffer::
////////////////////////////////////////////////////////////////////
bool wglGraphicsBuffer::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
@ -86,7 +87,37 @@ begin_frame() {
}
}
return GraphicsBuffer::begin_frame();
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsBuffer::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wglGraphicsBuffer::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////

View File

@ -47,6 +47,7 @@ public:
virtual ~wglGraphicsBuffer();
virtual bool begin_frame();
virtual void end_frame();
virtual void select_cube_map(int cube_map_index);
virtual void make_current();

View File

@ -147,6 +147,54 @@ wglGraphicsWindow::
~wglGraphicsWindow() {
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsWindow::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
// should do whatever setup is required, and return true
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wglGraphicsWindow::
begin_frame() {
begin_frame_spam();
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
auto_resize();
if (needs_context()) {
if (!make_context()) {
return false;
}
}
make_current();
begin_render_texture();
clear_cube_map_selection();
return _gsg->begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsWindow::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void wglGraphicsWindow::
end_frame() {
end_frame_spam();
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
_gsg->end_frame();
end_render_texture();
copy_to_textures();
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
clear_cube_map_selection();
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsWindow::make_context
// Access: Public, Virtual

View File

@ -33,10 +33,11 @@ public:
const string &name);
virtual ~wglGraphicsWindow();
virtual bool begin_frame();
virtual void end_frame();
virtual bool make_context();
virtual void make_current();
virtual void release_gsg();
virtual void begin_flip();
protected: