diff --git a/panda/src/display/graphicsBuffer.cxx b/panda/src/display/graphicsBuffer.cxx index 702bc0509f..b98dc38b34 100644 --- a/panda/src/display/graphicsBuffer.cxx +++ b/panda/src/display/graphicsBuffer.cxx @@ -41,19 +41,19 @@ GraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe, << "Creating new offscreen buffer " << get_name() << "\n"; } - _overlay_display_region->compute_pixels(_x_size, _y_size); + _overlay_display_region->compute_pixels(_size.get_x(), _size.get_y()); _open_request = OR_none; } //////////////////////////////////////////////////////////////////// // Function: GraphicsBuffer::Destructor // Access: Published, Virtual -// Description: +// Description: //////////////////////////////////////////////////////////////////// GraphicsBuffer:: ~GraphicsBuffer() { } - + //////////////////////////////////////////////////////////////////// // Function: GraphicsBuffer::set_size // Access: Public, Virtual diff --git a/panda/src/display/graphicsBuffer.h b/panda/src/display/graphicsBuffer.h index 5cda4fa5b5..cf6600347b 100644 --- a/panda/src/display/graphicsBuffer.h +++ b/panda/src/display/graphicsBuffer.h @@ -40,7 +40,7 @@ protected: PUBLISHED: virtual ~GraphicsBuffer(); - void set_size(int x, int y); + virtual void set_size(int x, int y); public: virtual void request_open(); diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index c5afb051c7..2b746ff09d 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -150,6 +150,25 @@ get_rtm_mode(int i) const { return cdata->_textures[i]._rtm_mode; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::get_size +// Access: Published +// Description: Returns the visible size of the window or buffer, if +// it is known. In certain cases (e.g. fullscreen +// windows), the size may not be known until after the +// object has been fully created. Check has_size() +// first. +// +// Certain objects (like windows) may change size +// spontaneously; this method is not thread-safe. To +// get the size of a window in a thread-safe manner, +// query get_properties(). +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase2i &GraphicsOutput:: +get_size() const { + return _size; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::get_x_size // Access: Published @@ -166,7 +185,7 @@ get_rtm_mode(int i) const { //////////////////////////////////////////////////////////////////// INLINE int GraphicsOutput:: get_x_size() const { - return _x_size; + return _size.get_x(); } //////////////////////////////////////////////////////////////////// @@ -185,7 +204,7 @@ get_x_size() const { //////////////////////////////////////////////////////////////////// INLINE int GraphicsOutput:: get_y_size() const { - return _y_size; + return _size.get_y(); } //////////////////////////////////////////////////////////////////// @@ -198,7 +217,7 @@ get_y_size() const { //////////////////////////////////////////////////////////////////// INLINE int GraphicsOutput:: get_fb_x_size() const { - return max(int(_x_size * get_pixel_factor()), 1); + return max(int(_size.get_x() * get_pixel_factor()), 1); } //////////////////////////////////////////////////////////////////// @@ -211,7 +230,7 @@ get_fb_x_size() const { //////////////////////////////////////////////////////////////////// INLINE int GraphicsOutput:: get_fb_y_size() const { - return max(int(_y_size * get_pixel_factor()), 1); + return max(int(_size.get_y() * get_pixel_factor()), 1); } //////////////////////////////////////////////////////////////////// @@ -226,7 +245,7 @@ get_fb_y_size() const { INLINE int GraphicsOutput:: get_sbs_left_x_size() const { PN_stdfloat left_w = _sbs_left_dimensions[1] - _sbs_left_dimensions[0]; - return max(int(_x_size * left_w), 1); + return max(int(_size.get_x() * left_w), 1); } //////////////////////////////////////////////////////////////////// @@ -241,7 +260,7 @@ get_sbs_left_x_size() const { INLINE int GraphicsOutput:: get_sbs_left_y_size() const { PN_stdfloat left_h = _sbs_left_dimensions[3] - _sbs_left_dimensions[2]; - return max(int(_y_size * left_h), 1); + return max(int(_size.get_y() * left_h), 1); } //////////////////////////////////////////////////////////////////// @@ -256,7 +275,7 @@ get_sbs_left_y_size() const { INLINE int GraphicsOutput:: get_sbs_right_x_size() const { PN_stdfloat right_w = _sbs_right_dimensions[1] - _sbs_right_dimensions[0]; - return max(int(_x_size * right_w), 1); + return max(int(_size.get_x() * right_w), 1); } //////////////////////////////////////////////////////////////////// @@ -271,7 +290,7 @@ get_sbs_right_x_size() const { INLINE int GraphicsOutput:: get_sbs_right_y_size() const { PN_stdfloat right_h = _sbs_right_dimensions[3] - _sbs_right_dimensions[2]; - return max(int(_y_size * right_h), 1); + return max(int(_size.get_y() * right_h), 1); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 273c9d9ae7..4fd7ccc435 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -78,7 +78,8 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, bool default_stereo_flags) : _lock("GraphicsOutput"), _cull_window_pcollector(_cull_pcollector, name), - _draw_window_pcollector(_draw_pcollector, name) + _draw_window_pcollector(_draw_pcollector, name), + _size(0, 0) { #ifdef DO_MEMORY_USAGE MemoryUsage::update_type(this, this); @@ -90,13 +91,11 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, _fb_properties = fb_prop; _name = name; _creation_flags = flags; - _x_size = _y_size = 0; _has_size = win_prop.has_size(); _is_nonzero_size = false; if (_has_size) { - _x_size = win_prop.get_x_size(); - _y_size = win_prop.get_y_size(); - _is_nonzero_size = (_x_size > 0 && _y_size > 0); + _size = win_prop.get_size(); + _is_nonzero_size = (_size[0] > 0 && _size[1] > 0); } if (_creation_flags & GraphicsPipe::BF_size_track_host) { // If we're tracking the host size, we assume we'll be nonzero @@ -546,14 +545,14 @@ set_inverted(bool inverted) { if (_inverted != inverted) { _inverted = inverted; - if (_y_size != 0) { + if (get_y_size() != 0) { // All of our DisplayRegions need to recompute their pixel // positions now. TotalDisplayRegions::iterator dri; for (dri = _total_display_regions.begin(); dri != _total_display_regions.end(); ++dri) { - (*dri)->compute_pixels(_x_size, _y_size); + (*dri)->compute_pixels(get_x_size(), get_y_size()); } } } @@ -1102,7 +1101,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig, NodePath GraphicsOutput:: get_texture_card() { if (_texture_card == 0) { - PT(GeomVertexData) vdata = create_texture_card_vdata(_x_size, _y_size); + PT(GeomVertexData) vdata = create_texture_card_vdata(get_x_size(), get_y_size()); PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); strip->set_shade_model(Geom::SM_uniform); strip->add_next_vertices(4); @@ -1262,11 +1261,10 @@ clear_pipe() { //////////////////////////////////////////////////////////////////// void GraphicsOutput:: set_size_and_recalc(int x, int y) { - _x_size = x; - _y_size = y; + _size.set(x, y); _has_size = true; - _is_nonzero_size = (_x_size > 0 && _y_size > 0); + _is_nonzero_size = (x > 0 && y > 0); int fb_x_size = get_fb_x_size(); int fb_y_size = get_fb_y_size(); @@ -1498,7 +1496,7 @@ process_events() { void GraphicsOutput:: pixel_factor_changed() { if (_has_size) { - set_size_and_recalc(_x_size, _y_size); + set_size_and_recalc(get_x_size(), get_y_size()); } } diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index f138a64433..7196fc2bcf 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -128,10 +128,11 @@ PUBLISHED: INLINE RenderTexturePlane get_texture_plane(int i=0) const; INLINE RenderTextureMode get_rtm_mode(int i=0) const; void clear_render_textures(); - void add_render_texture(Texture *tex, RenderTextureMode mode, + void add_render_texture(Texture *tex, RenderTextureMode mode, RenderTexturePlane bitplane=RTP_COUNT); void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram); + INLINE const LVecBase2i &get_size() const; INLINE int get_x_size() const; INLINE int get_y_size() const; INLINE int get_fb_x_size() const; @@ -290,7 +291,7 @@ protected: private: PT(GeomVertexData) create_texture_card_vdata(int x, int y); - + DisplayRegion *add_display_region(DisplayRegion *display_region); bool do_remove_display_region(DisplayRegion *display_region); @@ -323,7 +324,7 @@ protected: RenderTextureMode _rtm_mode; }; typedef pvector RenderTextures; - + private: int _sort; int _child_sort; @@ -346,9 +347,9 @@ protected: // have, we don't auto-close the buffer (since that would deallocate // the memory associated with the texture). pvector _hold_textures; - + protected: - LightMutex _lock; + LightMutex _lock; // protects _display_regions. PT(DisplayRegion) _overlay_display_region; typedef pvector< PT(DisplayRegion) > TotalDisplayRegions; @@ -382,8 +383,7 @@ protected: protected: int _creation_flags; - int _x_size; - int _y_size; + LVecBase2i _size; bool _has_size; bool _is_valid; bool _is_nonzero_size; @@ -394,7 +394,7 @@ protected: static PStatCollector _draw_pcollector; PStatCollector _cull_window_pcollector; PStatCollector _draw_window_pcollector; - + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 36be7cb270..cd4e3c3e43 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -170,8 +170,7 @@ request_properties(const WindowProperties &requested_properties) { // stick. This is helpful for the MultitexReducer, which needs to // know the size of the textures that it will be working with, // even if the texture hasn't been fully generated yet. - _x_size = _requested_properties.get_x_size(); - _y_size = _requested_properties.get_y_size(); + _size = _requested_properties.get_size(); // Don't set _has_size yet, because we don't really know yet. } diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx index b90f76f070..cd49d18ca8 100644 --- a/panda/src/display/parasiteBuffer.cxx +++ b/panda/src/display/parasiteBuffer.cxx @@ -27,15 +27,15 @@ TypeHandle ParasiteBuffer::_type_handle; ParasiteBuffer:: ParasiteBuffer(GraphicsOutput *host, const string &name, int x_size, int y_size, int flags) : - GraphicsOutput(host->get_engine(), host->get_pipe(), + GraphicsOutput(host->get_engine(), host->get_pipe(), name, host->get_fb_properties(), - WindowProperties::size(x_size, y_size), flags, + WindowProperties::size(x_size, y_size), flags, host->get_gsg(), host, false) { #ifdef DO_MEMORY_USAGE MemoryUsage::update_type(this, this); #endif - + if (display_cat.is_debug()) { display_cat.debug() << "Creating new parasite buffer " << get_name() @@ -43,25 +43,24 @@ ParasiteBuffer(GraphicsOutput *host, const string &name, } _creation_flags = flags; - + if (flags & GraphicsPipe::BF_size_track_host) { - x_size = host->get_x_size(); - y_size = host->get_y_size(); + _size = host->get_size(); + } else { + _size.set(x_size, y_size); } - - _x_size = x_size; - _y_size = y_size; + _has_size = true; - _overlay_display_region->compute_pixels(_x_size, _y_size); + _overlay_display_region->compute_pixels(_size.get_x(), _size.get_y()); _is_valid = true; - + set_inverted(host->get_gsg()->get_copy_texture_inverted()); } //////////////////////////////////////////////////////////////////// // Function: ParasiteBuffer::Destructor // Access: Published, Virtual -// Description: +// Description: //////////////////////////////////////////////////////////////////// ParasiteBuffer:: ~ParasiteBuffer() { @@ -201,19 +200,18 @@ begin_frame(FrameMode mode, Thread *current_thread) { } if (_creation_flags & GraphicsPipe::BF_size_track_host) { - if ((_host->get_x_size() != _x_size)|| - (_host->get_y_size() != _y_size)) { + if (_host->get_size() != _size) { set_size_and_recalc(_host->get_x_size(), _host->get_y_size()); } } else { - if (_host->get_x_size() < _x_size || - _host->get_y_size() < _y_size) { - set_size_and_recalc(min(_x_size, _host->get_x_size()), - min(_y_size, _host->get_y_size())); + if (_host->get_x_size() < get_x_size() || + _host->get_y_size() < get_y_size()) { + set_size_and_recalc(min(get_x_size(), _host->get_x_size()), + min(get_y_size(), _host->get_y_size())); } } - + clear_cube_map_selection(); return true; } diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 79de507955..232d33044a 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -155,8 +155,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { } } if (_creation_flags & GraphicsPipe::BF_size_track_host) { - if ((_host->get_x_size() != _x_size)|| - (_host->get_y_size() != _y_size)) { + if (_host->get_size() != _size) { // We also need to rebuild if we need to change size. _needs_rebuild = true; } @@ -277,14 +276,14 @@ rebuild_bitplanes() { // Calculate bitplane size. This can be larger than the buffer. if (_creation_flags & GraphicsPipe::BF_size_track_host) { - if ((_host->get_x_size() != _x_size)|| - (_host->get_y_size() != _y_size)) { + if (_host->get_size() != _size) { set_size_and_recalc(_host->get_x_size(), _host->get_y_size()); } } - int bitplane_x = _x_size; - int bitplane_y = _y_size; + + int bitplane_x = get_x_size(); + int bitplane_y = get_y_size(); if (Texture::get_textures_power_2() != ATS_none) { bitplane_x = Texture::up_to_power_2(bitplane_x); bitplane_y = Texture::up_to_power_2(bitplane_y); @@ -602,7 +601,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, if (tex->get_texture_type() != Texture::TT_cube_map && _rb_size_z > 1) { tex->set_z_size(_rb_size_z); } - tex->set_pad_size(_rb_size_x - _x_size, _rb_size_y - _y_size); + tex->set_pad_size(_rb_size_x - get_x_size(), _rb_size_y - get_y_size()); // Adjust the texture format based on the requested framebuffer settings. switch (slot) { @@ -1072,6 +1071,10 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { gtc->set_active(true); _texture_contexts.push_back(gtc); + // It seems that binding the texture is necessary before binding + // to a framebuffer attachment. + glgsg->apply_texture(gtc); + #ifndef OPENGLES GLclampf priority = 1.0f; glPrioritizeTextures(1, >c->_index, &priority); @@ -1191,7 +1194,7 @@ end_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: set_size(int x, int y) { - if (_x_size != x || _y_size != y) { + if (_size.get_x() != x || _size.get_y() != y) { _needs_rebuild = true; } diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.cxx b/panda/src/glxdisplay/glxGraphicsBuffer.cxx index f21a08d62d..1e2ead3f44 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.cxx +++ b/panda/src/glxdisplay/glxGraphicsBuffer.cxx @@ -178,7 +178,7 @@ open_buffer() { // new one that shares with the old gsg. DCAST_INTO_R(glxgsg, _gsg, false); - if (!glxgsg->_context_has_pbuffer || + if (!glxgsg->_context_has_pbuffer || !glxgsg->get_fb_properties().subsumes(_fb_properties)) { // We need a new pixel format, and hence a new GSG. glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg); @@ -186,7 +186,7 @@ open_buffer() { _gsg = glxgsg; } } - + if (glxgsg->_fbconfig == None || !glxgsg->_context_has_pbuffer) { // If we didn't use an fbconfig to create the GSG, or it doesn't // support buffers, we can't create a PBuffer. @@ -204,15 +204,15 @@ open_buffer() { nassertr(n < max_attrib_list, false); attrib_list[n] = (int)None; _pbuffer = glxgsg->_glXCreateGLXPbufferSGIX(glxgsg->_display, glxgsg->_fbconfig, - _x_size, _y_size, attrib_list); + get_x_size(), get_y_size(), attrib_list); } else { // The official GLX 1.3 version passes in the size in the attrib // list. attrib_list[n++] = GLX_PBUFFER_WIDTH; - attrib_list[n++] = _x_size; + attrib_list[n++] = get_x_size(); attrib_list[n++] = GLX_PBUFFER_HEIGHT; - attrib_list[n++] = _y_size; - + attrib_list[n++] = get_y_size(); + nassertr(n < max_attrib_list, false); attrib_list[n] = (int)None; _pbuffer = glxgsg->_glXCreatePbuffer(glxgsg->_display, glxgsg->_fbconfig, diff --git a/panda/src/glxdisplay/glxGraphicsPixmap.cxx b/panda/src/glxdisplay/glxGraphicsPixmap.cxx index 29585ae324..e98e338df0 100644 --- a/panda/src/glxdisplay/glxGraphicsPixmap.cxx +++ b/panda/src/glxdisplay/glxGraphicsPixmap.cxx @@ -213,8 +213,8 @@ open_buffer() { } } - _x_pixmap = XCreatePixmap(_display, _drawable, - _x_size, _y_size, visual_info->depth); + _x_pixmap = XCreatePixmap(_display, _drawable, + get_x_size(), get_y_size(), visual_info->depth); if (_x_pixmap == None) { glxdisplay_cat.error() << "Failed to create X pixmap.\n";