Panda3D
 All Classes Functions Variables Enumerations
parasiteBuffer.cxx
00001 // Filename: parasiteBuffer.cxx
00002 // Created by:  drose (27Feb04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "parasiteBuffer.h"
00016 #include "texture.h"
00017 
00018 TypeHandle ParasiteBuffer::_type_handle;
00019 
00020 ////////////////////////////////////////////////////////////////////
00021 //     Function: ParasiteBuffer::Constructor
00022 //       Access: Public
00023 //  Description: Normally, the ParasiteBuffer constructor is not
00024 //               called directly; these are created instead via the
00025 //               GraphicsEngine::make_parasite() function.
00026 ////////////////////////////////////////////////////////////////////
00027 ParasiteBuffer::
00028 ParasiteBuffer(GraphicsOutput *host, const string &name,
00029                int x_size, int y_size, int flags) :
00030   GraphicsOutput(host->get_engine(), host->get_pipe(), 
00031                  name, host->get_fb_properties(),
00032                  WindowProperties::size(x_size, y_size), flags, 
00033                  host->get_gsg(), host, false)
00034 {
00035 #ifdef DO_MEMORY_USAGE
00036   MemoryUsage::update_type(this, this);
00037 #endif
00038   
00039   if (display_cat.is_debug()) {
00040     display_cat.debug()
00041       << "Creating new parasite buffer " << get_name()
00042       << " on " << _host->get_name() << "\n";
00043   }
00044 
00045   _creation_flags = flags;
00046   
00047   if (flags & GraphicsPipe::BF_size_track_host) {
00048     x_size = host->get_x_size();
00049     y_size = host->get_y_size();
00050   }
00051   
00052   _x_size = x_size;
00053   _y_size = y_size;
00054   _has_size = true;
00055   _overlay_display_region->compute_pixels(_x_size, _y_size);
00056   _is_valid = true;
00057   
00058   set_inverted(host->get_gsg()->get_copy_texture_inverted());
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function: ParasiteBuffer::Destructor
00063 //       Access: Published, Virtual
00064 //  Description: 
00065 ////////////////////////////////////////////////////////////////////
00066 ParasiteBuffer::
00067 ~ParasiteBuffer() {
00068   _is_valid = false;
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: ParasiteBuffer::is_active
00073 //       Access: Published, Virtual
00074 //  Description: Returns true if the window is ready to be rendered
00075 //               into, false otherwise.
00076 ////////////////////////////////////////////////////////////////////
00077 bool ParasiteBuffer::
00078 is_active() const {
00079   return GraphicsOutput::is_active() && _host->is_active();
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: ParasiteBuffer::set_size
00084 //       Access: Public, Virtual
00085 //  Description: This is called by the GraphicsEngine to request that
00086 //               the buffer resize itself.  Although calls to get the
00087 //               size will return the new value, much of the actual
00088 //               resizing work doesn't take place until the next
00089 //               begin_frame.  Not all buffers are resizeable.
00090 ////////////////////////////////////////////////////////////////////
00091 void ParasiteBuffer::
00092 set_size(int x, int y) {
00093   if ((_creation_flags & GraphicsPipe::BF_resizeable) == 0) {
00094     nassert_raise("Cannot resize buffer unless it is created with BF_resizeable flag");
00095     return;
00096   }
00097   set_size_and_recalc(x, y);
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: ParasiteBuffer::set_size_and_recalc
00102 //       Access: Public
00103 //  Description: 
00104 ////////////////////////////////////////////////////////////////////
00105 void ParasiteBuffer::
00106 set_size_and_recalc(int x, int y) {
00107   if (!(_creation_flags & GraphicsPipe::BF_size_track_host)) {
00108     if (_creation_flags & GraphicsPipe::BF_size_power_2) {
00109       x = Texture::down_to_power_2(x);
00110       y = Texture::down_to_power_2(y);
00111     }
00112     if (_creation_flags & GraphicsPipe::BF_size_square) {
00113       x = y = min(x, y);
00114     }
00115   }
00116 
00117   GraphicsOutput::set_size_and_recalc(x, y);
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: ParasiteBuffer::flip_ready
00122 //       Access: Public, Virtual
00123 //  Description: Returns true if a frame has been rendered and needs
00124 //               to be flipped, false otherwise.
00125 ////////////////////////////////////////////////////////////////////
00126 bool ParasiteBuffer::
00127 flip_ready() const {
00128   nassertr(_host != NULL, false);
00129   return _host->flip_ready();
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: ParasiteBuffer::begin_flip
00134 //       Access: Public, Virtual
00135 //  Description: This function will be called within the draw thread
00136 //               after end_frame() has been called on all windows, to
00137 //               initiate the exchange of the front and back buffers.
00138 //
00139 //               This should instruct the window to prepare for the
00140 //               flip at the next video sync, but it should not wait.
00141 //
00142 //               We have the two separate functions, begin_flip() and
00143 //               end_flip(), to make it easier to flip all of the
00144 //               windows at the same time.
00145 ////////////////////////////////////////////////////////////////////
00146 void ParasiteBuffer::
00147 begin_flip() {
00148   nassertv(_host != NULL);
00149   _host->begin_flip();
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: ParasiteBuffer::ready_flip
00154 //       Access: Public, Virtual
00155 //  Description: This function will be called within the draw thread
00156 //               after end_frame() has been called on all windows, to
00157 //               initiate the exchange of the front and back buffers.
00158 //
00159 //               This should instruct the window to prepare for the
00160 //               flip when it is command but not actually flip
00161 //
00162 ////////////////////////////////////////////////////////////////////
00163 void ParasiteBuffer::
00164 ready_flip() {
00165   nassertv(_host != NULL);
00166   _host->ready_flip();
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function: ParasiteBuffer::end_flip
00171 //       Access: Public, Virtual
00172 //  Description: This function will be called within the draw thread
00173 //               after begin_flip() has been called on all windows, to
00174 //               finish the exchange of the front and back buffers.
00175 //
00176 //               This should cause the window to wait for the flip, if
00177 //               necessary.
00178 ////////////////////////////////////////////////////////////////////
00179 void ParasiteBuffer::
00180 end_flip() {
00181   nassertv(_host != NULL);
00182   _host->end_flip();
00183   _flip_ready = false;
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: ParasiteBuffer::begin_frame
00188 //       Access: Public, Virtual
00189 //  Description: This function will be called within the draw thread
00190 //               before beginning rendering for a given frame.  It
00191 //               should do whatever setup is required, and return true
00192 //               if the frame should be rendered, or false if it
00193 //               should be skipped.
00194 ////////////////////////////////////////////////////////////////////
00195 bool ParasiteBuffer::
00196 begin_frame(FrameMode mode, Thread *current_thread) {
00197   begin_frame_spam(mode);
00198 
00199   if (!_host->begin_frame(FM_parasite, current_thread)) {
00200     return false;
00201   }
00202 
00203   if (_creation_flags & GraphicsPipe::BF_size_track_host) {
00204     if ((_host->get_x_size() != _x_size)||
00205         (_host->get_y_size() != _y_size)) {
00206       set_size_and_recalc(_host->get_x_size(),
00207                           _host->get_y_size());
00208     }
00209   } else {
00210     if (_host->get_x_size() < _x_size ||
00211         _host->get_y_size() < _y_size) {
00212       set_size_and_recalc(min(_x_size, _host->get_x_size()),
00213                           min(_y_size, _host->get_y_size()));
00214     }
00215   }
00216   
00217   clear_cube_map_selection();
00218   return true;
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: ParasiteBuffer::end_frame
00223 //       Access: Public, Virtual
00224 //  Description: This function will be called within the draw thread
00225 //               after rendering is completed for a given frame.  It
00226 //               should do whatever finalization is required.
00227 ////////////////////////////////////////////////////////////////////
00228 void ParasiteBuffer::
00229 end_frame(FrameMode mode, Thread *current_thread) {
00230   end_frame_spam(mode);
00231 
00232   nassertv(_gsg != (GraphicsStateGuardian *)NULL);
00233 
00234   _host->end_frame(FM_parasite, current_thread);
00235 
00236   if (mode == FM_refresh) {
00237     return;
00238   }
00239   
00240   if (mode == FM_render) {
00241     promote_to_copy_texture();
00242     copy_to_textures();
00243     clear_cube_map_selection();
00244   }
00245 }
00246 
00247 ////////////////////////////////////////////////////////////////////
00248 //     Function: ParasiteBuffer::get_host
00249 //       Access: Public, Virtual
00250 //  Description: This is normally called only from within
00251 //               make_texture_buffer().  When called on a
00252 //               ParasiteBuffer, it returns the host of that buffer;
00253 //               but when called on some other buffer, it returns the
00254 //               buffer itself.
00255 ////////////////////////////////////////////////////////////////////
00256 GraphicsOutput *ParasiteBuffer::
00257 get_host() {
00258   return _host;
00259 }
00260 
 All Classes Functions Variables Enumerations