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