Panda3D
 All Classes Functions Variables Enumerations
videoTexture.cxx
1 // Filename: videoTexture.cxx
2 // Created by: drose (21Sep05)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pandabase.h"
16 
17 #include "videoTexture.h"
18 #include "clockObject.h"
19 #include "config_gobj.h"
20 
21 TypeHandle VideoTexture::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: VideoTexture::Constructor
25 // Access: Protected
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 VideoTexture::
29 VideoTexture(const string &name) :
30  Texture(name)
31 {
32  // We don't want to try to compress each frame as it's loaded.
33  Texture::CDWriter cdata(Texture::_cycler, true);
34  cdata->_compression = CM_off;
35 
36  _video_width = 0;
37  _video_height = 0;
38 
39  _last_frame_update = 0;
40  _current_frame = -1;
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: VideoTexture::Copy Constructor
45 // Access: Protected
46 // Description:
47 ////////////////////////////////////////////////////////////////////
48 VideoTexture::
49 VideoTexture(const VideoTexture &copy) :
50  Texture(copy),
51  AnimInterface(copy),
52  _video_width(copy._video_width),
53  _video_height(copy._video_height),
54  _last_frame_update(copy._last_frame_update),
55  _current_frame(copy._current_frame)
56 {
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: VideoTexture::get_keep_ram_image
61 // Access: Published, Virtual
62 // Description: Returns the flag that indicates whether this Texture
63 // is eligible to have its main RAM copy of the texture
64 // memory dumped when the texture is prepared for
65 // rendering. See set_keep_ram_image().
66 ////////////////////////////////////////////////////////////////////
67 bool VideoTexture::
69  // A VideoTexture should never dump its RAM image.
70  return true;
71 }
72 
73 ////////////////////////////////////////////////////////////////////
74 // Function: VideoTexture::has_cull_callback
75 // Access: Public, Virtual
76 // Description: Should be overridden by derived classes to return
77 // true if cull_callback() has been defined. Otherwise,
78 // returns false to indicate cull_callback() does not
79 // need to be called for this node during the cull
80 // traversal.
81 ////////////////////////////////////////////////////////////////////
82 bool VideoTexture::
84  return true;
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: VideoTexture::cull_callback
89 // Access: Public, Virtual
90 // Description: If has_cull_callback() returns true, this function
91 // will be called during the cull traversal to perform
92 // any additional operations that should be performed at
93 // cull time.
94 //
95 // This is called each time the Texture is discovered
96 // applied to a Geom in the traversal. It should return
97 // true if the Geom is visible, false if it should be
98 // omitted.
99 ////////////////////////////////////////////////////////////////////
100 bool VideoTexture::
102  // Strictly speaking, the cull_callback() method isn't necessary for
103  // VideoTexture, since the get_ram_image() function is already
104  // overloaded to update itself if necessary. However, we define it
105  // anyway, to move the update calculation into the cull traversal
106  // rather than the draw traversal.
107  ((VideoTexture *)this)->reconsider_dirty();
108  return true;
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: VideoTexture::set_video_size
113 // Access: Protected
114 // Description: Should be called by a derived class to set the size
115 // of the video when it is loaded. Assumes the lock is
116 // held.
117 ////////////////////////////////////////////////////////////////////
118 void VideoTexture::
119 set_video_size(int video_width, int video_height) {
120  _video_width = video_width;
121  _video_height = video_height;
122  set_orig_file_size(video_width, video_height);
123 
124  Texture::CDWriter cdata(Texture::_cycler, true);
125  do_set_pad_size(cdata,
126  max(cdata->_x_size - _video_width, 0),
127  max(cdata->_y_size - _video_height, 0),
128  0);
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: VideoTexture::do_has_ram_image
133 // Access: Protected, Virtual
134 // Description: Returns true if the Texture has its image contents
135 // available in main RAM, false if it exists only in
136 // texture memory or in the prepared GSG context.
137 ////////////////////////////////////////////////////////////////////
138 bool VideoTexture::
139 do_has_ram_image(const Texture::CData *cdata) const {
140  int this_frame = ClockObject::get_global_clock()->get_frame_count();
141  if (this_frame != _last_frame_update) {
142  return false;
143  }
144  return !cdata->_ram_images.empty() && !cdata->_ram_images[0]._image.empty();
145 }
146 
147 ////////////////////////////////////////////////////////////////////
148 // Function: VideoTexture::reconsider_dirty
149 // Access: Protected, Virtual
150 // Description: Called by TextureContext to give the Texture a chance
151 // to mark itself dirty before rendering, if necessary.
152 ////////////////////////////////////////////////////////////////////
153 void VideoTexture::
154 reconsider_dirty() {
155  consider_update();
156 }
157 
158 
159 ////////////////////////////////////////////////////////////////////
160 // Function: VideoTexture::unlocked_ensure_ram_image
161 // Access: Protected, Virtual
162 // Description: If the texture has a ram image already, this acquires
163 // the CData write lock and returns it.
164 //
165 // If the texture lacks a ram image, this performs
166 // do_reload_ram_image(), but without holding the lock
167 // on this particular Texture object, to avoid holding
168 // the lock across what might be a slow operation.
169 // Instead, the reload is performed in a copy of the
170 // texture object, and then the lock is acquired and the
171 // data is copied in.
172 //
173 // In any case, the return value is a locked CData
174 // object, which must be released with an explicit call
175 // to release_write(). The CData object will have a ram
176 // image unless for some reason do_reload_ram_image()
177 // fails.
178 ////////////////////////////////////////////////////////////////////
179 Texture::CData *VideoTexture::
180 unlocked_ensure_ram_image(bool allow_compression) {
181  consider_update();
182 
183  Thread *current_thread = Thread::get_current_thread();
184  Texture::CData *cdata = Texture::_cycler.write_upstream(false, current_thread);
185  return cdata;
186 }
187 
188 ////////////////////////////////////////////////////////////////////
189 // Function: VideoTexture::do_reload_ram_image
190 // Access: Protected, Virtual
191 // Description: Called when the Texture image is required but the ram
192 // image is not available, this will reload it from disk
193 // or otherwise do whatever is required to make it
194 // available, if possible.
195 ////////////////////////////////////////////////////////////////////
196 void VideoTexture::
197 do_reload_ram_image(Texture::CData *cdata, bool) {
198  consider_update();
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function: VideoTexture::do_can_reload
203 // Access: Protected, Virtual
204 // Description: Returns true if we can safely call
205 // do_unlock_and_reload_ram_image() in order to make the
206 // image available, or false if we shouldn't do this
207 // (because we know from a priori knowledge that it
208 // wouldn't work anyway).
209 ////////////////////////////////////////////////////////////////////
210 bool VideoTexture::
211 do_can_reload(const Texture::CData *cdata) const {
212  return true;
213 }
214 
215 ////////////////////////////////////////////////////////////////////
216 // Function: VideoTexture::do_adjust_this_size
217 // Access: Protected, Virtual
218 // Description: Works like adjust_size, but also considers the
219 // texture class. Movie textures, for instance, always
220 // pad outwards, never scale down.
221 ////////////////////////////////////////////////////////////////////
222 bool VideoTexture::
223 do_adjust_this_size(const Texture::CData *cdata_tex,
224  int &x_size, int &y_size, const string &name,
225  bool for_padding) const {
226  AutoTextureScale ats = do_get_auto_texture_scale(cdata_tex);
227  if (ats != ATS_none) {
228  ats = ATS_pad;
229  }
230 
231  return adjust_size(x_size, y_size, name, for_padding, ats);
232 }
233 
234 ////////////////////////////////////////////////////////////////////
235 // Function: VideoTexture::consider_update
236 // Access: Protected, Virtual
237 // Description: Calls update_frame() if the current frame has
238 // changed.
239 ////////////////////////////////////////////////////////////////////
240 void VideoTexture::
241 consider_update() {
242  int this_frame = ClockObject::get_global_clock()->get_frame_count();
243  if (this_frame != _last_frame_update) {
244  int frame = get_frame();
245  if (_current_frame != frame) {
246  Texture::CDWriter cdata(Texture::_cycler, false);
247  do_update_frame(cdata, frame);
248  _current_frame = frame;
249  }
250  _last_frame_update = this_frame;
251  }
252 }
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:271
static bool adjust_size(int &x_size, int &y_size, const string &name, bool for_padding, AutoTextureScale auto_texture_scale=ATS_unspecified)
Computes the proper size of the texture, based on the original size, the filename, and the resizing whims of the config file.
Definition: texture.cxx:2486
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined...
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:75
void set_orig_file_size(int x, int y, int z=1)
Specifies the size of the texture as it exists in its original disk file, before any Panda scaling...
Definition: texture.cxx:1783
This collects together the pieces of data that are accumulated for each node while walking the scene ...
The base class for a family of animated Textures that take their input from a video source...
Definition: videoTexture.h:31
This is the fundamental interface for things that have a play/loop/stop type interface for frame-base...
Definition: animInterface.h:39
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
int get_frame() const
Returns the current integer frame number.
int get_frame_count(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of times tick() has been called since the ClockObject was created, or since it was last reset.
Definition: clockObject.I:113
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A thread; that is, a lightweight process.
Definition: thread.h:51
CycleDataType * write_upstream(bool force_to_0, Thread *current_thread)
See PipelineCyclerBase::write_upstream().
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
virtual bool get_keep_ram_image() const
Returns the flag that indicates whether this Texture is eligible to have its main RAM copy of the tex...