00001 /*!@file Psycho/DisplayController.H a thread to abstract the gathering 00002 of stimulus commands from a shared buffer, and render them into the 00003 current SDL display. */ 00004 00005 // //////////////////////////////////////////////////////////////////// // 00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00007 // University of Southern California (USC) and the iLab at USC. // 00008 // See http://iLab.usc.edu for information about this project. // 00009 // //////////////////////////////////////////////////////////////////// // 00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00012 // in Visual Environments, and Applications'' by Christof Koch and // 00013 // Laurent Itti, California Institute of Technology, 2001 (patent // 00014 // pending; application number 09/912,225 filed July 23, 2001; see // 00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00016 // //////////////////////////////////////////////////////////////////// // 00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00018 // // 00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00020 // redistribute it and/or modify it under the terms of the GNU General // 00021 // Public License as published by the Free Software Foundation; either // 00022 // version 2 of the License, or (at your option) any later version. // 00023 // // 00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00027 // PURPOSE. See the GNU General Public License for more details. // 00028 // // 00029 // You should have received a copy of the GNU General Public License // 00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00032 // Boston, MA 02111-1307 USA. // 00033 // //////////////////////////////////////////////////////////////////// // 00034 // 00035 // Primary maintainer for this file: David Berg <dberg@usc.edu> 00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Psycho/DisplayController.H $ 00037 00038 #ifndef PSYCHO_DISPLAYCONTROLLER_H_FEFINED 00039 #define PSYCHO_DISPLAYCONTROLLER_H_FEFINED 00040 00041 #include "Component/EventLog.H" 00042 #include "Util/JobServer.H" 00043 #include "Util/SharedBuffer.H" 00044 #include "Util/Semaphore.H" 00045 #include "Raster/GenericFrame.H" 00046 #include "Psycho/PsychoDisplay.H" 00047 #include "Psycho/StimData.H" 00048 00049 #include <map> 00050 00051 // ###################################################################### 00052 //!A thread to control the psycho display from an external controller 00053 // ###################################################################### 00054 /*!This class is to be used by a StimController to to control the SDL 00055 display. Display commands are read through a shared buffer. Calling 00056 programs should no longer try to handle display themselves, but 00057 merely call the setBackground() to 'inject' the calling programs 00058 image into the DisplayController thread. The image will be rendered 00059 on the next display cycle in the background of the 00060 DisplayControllers current drawing instructions. */ 00061 00062 class DisplayController : public JobServer::Job 00063 { 00064 public: 00065 //!c'tor 00066 DisplayController(); 00067 00068 //!d'tor 00069 virtual ~DisplayController(); 00070 00071 //!set the display from the main calling programs display 00072 void setDisplay(nub::soft_ref<PsychoDisplay> display); 00073 00074 //!set the buffer to be shared with StimListener 00075 void setBuffer(rutz::shared_ptr<SharedBuffer<RexData*> > buffer); 00076 00077 //!set the log file 00078 void setEventLog(nub::soft_ref<EventLog> log); 00079 00080 //!push an event to the log, if uselinfo is true also display it to the screen 00081 void pushEvent(const std::string& msg, const bool& uselinfo = false); 00082 00083 //!halt the display controller's run loop 00084 void pause(bool pausestate); 00085 00086 //!set the current background 00087 void setBackground(const GenericFrame& gf, const int framenumber); 00088 00089 //! start the componenet and do any pre-display stuff. 00090 virtual void start(); 00091 00092 //!clean up and stop 00093 virtual void stop(); 00094 00095 // ###################################################################### 00096 // from JobServer::Job 00097 // ###################################################################### 00098 //!the actual work of the thread is here 00099 virtual void run(); 00100 00101 //!job name 00102 virtual const char* jobType() const; 00103 00104 //!return priority, 0 is highest 00105 virtual int priority() const; 00106 00107 private: 00108 // ###################################################################### 00109 // private drawing primitives for rendering onto the current SDL display 00110 // ###################################################################### 00111 //! wait for refresh draw, and reset the backGround image; 00112 void draw(const byte* parameters = NULL); 00113 00114 //! draw a circle on the sdl Display 00115 void drawCircle(const byte* parameters); 00116 00117 //!clear the current screen 00118 void clearScreen(const byte* parameters); 00119 00120 //!create a pop-out array, with possible multiple targets 00121 void createPopout(const byte* parameters); 00122 00123 // ###################################################################### 00124 // our private and functions 00125 // ###################################################################### 00126 DisplayController& operator=(const DisplayController& d); 00127 DisplayController(const DisplayController& d); 00128 00129 //!Display a video frame with an image overlayed, ignoring the 00130 //!transparent pixels. 00131 void overlayVideo(const Image<PixRGB<byte> >& over, const VideoFrame& frame, 00132 const PixRGB<byte>& transparentcolor, const uint framenum); 00133 00134 //!our shared display 00135 nub::soft_ref<PsychoDisplay> itsDisplay; 00136 00137 //! a shared buffer 00138 rutz::shared_ptr<SharedBuffer<RexData*> > itsBuffer; 00139 00140 //! a log file 00141 nub::soft_ref<EventLog> itsLog; 00142 00143 //! suspend until reset. 00144 volatile bool isPaused; 00145 00146 //!a flag to see if someone told us to stop 00147 volatile bool isDone; 00148 00149 //!a flag set when the rex system has called a vsync 00150 bool isRexReady; 00151 00152 //!This flag controls who actually calls syncScreen to flip the 00153 //!backbuffer. Normally, for static backgrounds Rex will decide when 00154 //!to render graphics to the screen, by sending a vertical blank 00155 //!code which will call our draw() function. When displaying video, 00156 //!to ensure proper frame rate, setBackground calls the syncscreen 00157 //!checking isRexReady and blitting any rex image before actually 00158 //!flipping the buffer. 00159 bool isVideoStream; 00160 00161 //!just to count the number of frames sent from rex 00162 long itsFrameCount; 00163 00164 //!to hold our background image, or video frame 00165 VideoFrame itsBackgroundFrame; 00166 00167 //!the current rex drawing. 00168 Image<PixRGB<byte> > itsRexImage; 00169 00170 //!A semaphore to actual do the pausing. 00171 Semaphore itsPauser; 00172 00173 //! A map to store function pointers to primitive drawing routines, 00174 //! that are keyed by the byte code from the Rex system that 00175 //! indicates the primitive type (e.g. circle, square etc) 00176 std::map<unsigned char, void (DisplayController::*)(unsigned char*)> itsFuncMap; 00177 }; 00178 00179 #endif 00180 // ###################################################################### 00181 /* So things look consistent in everyone's emacs... */ 00182 /* Local Variables: */ 00183 /* indent-tabs-mode: nil */ 00184 /* End: */