Nux

Merge lp:~thumper/nux/window-compositor into lp:nux

Proposed by Tim Penhey
Status: Merged
Merged at revision: 484
Proposed branch: lp:~thumper/nux/window-compositor
Merge into: lp:nux
Diff against target: 229 lines (+72/-75)
1 file modified
Nux/WindowCompositor.cpp (+72/-75)
To merge this branch: bzr merge lp:~thumper/nux/window-compositor
Reviewer Review Type Date Requested Status
Jay Taoko (community) Approve
Jason Smith (community) Approve
Review via email: mp+77084@code.launchpad.net

Description of the change

The rendering of the icons was causing the tooltip to call "PushToFront" while the rendering was being done. This invalidated the iterator if the iterator was on the last one i.e. the front most, as the front was moving. This caused the world to explode, or as we say in code SIGSEGV.

The fix is to have the rendering take a copy of the list it is about to render as we can't control what the views are going to do.

I reverse the list while making a copy using the rbegin(), rend() iterator constructor.

I also refactored the internals making use of temporary variables to reduce duplicate code.

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

+1

looks good tim

review: Approve
Revision history for this message
Jay Taoko (jaytaoko) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Nux/WindowCompositor.cpp'
2--- Nux/WindowCompositor.cpp 2011-09-20 06:03:43 +0000
3+++ Nux/WindowCompositor.cpp 2011-09-27 02:52:27 +0000
4@@ -113,16 +113,15 @@
5
6 WindowCompositor::RenderTargetTextures &WindowCompositor::GetWindowBuffer (BaseWindow *window)
7 {
8- RenderTargetTextures invalid;
9- RenderTargetTextures &ret = invalid;
10+ static RenderTargetTextures invalid;
11 std::map< BaseWindow*, RenderTargetTextures >::iterator it = _window_to_texture_map.find (window);
12
13 if (it != _window_to_texture_map.end())
14 {
15- return (*it).second;
16+ return it->second;
17 }
18-
19- return ret;
20+ LOG_WARN(logger) << "No RenderTargetTextures for window.";
21+ return invalid;
22 }
23
24 void WindowCompositor::RegisterWindow (BaseWindow *window)
25@@ -1394,50 +1393,61 @@
26 GetPainter().EmptyBackgroundStack();
27 }
28
29- void WindowCompositor::RenderTopViews (bool force_draw, std::list< ObjectWeakPtr<BaseWindow> >& WindowList, bool drawModal)
30+ void WindowCompositor::RenderTopViews(bool force_draw,
31+ WindowList& windows_to_render,
32+ bool drawModal)
33 {
34 // Before anything, deactivate the current frame buffer, set the viewport
35 // to the size of the display and call EmptyClippingRegion().
36 // Then call GetScissorRect() to get the size of the global clipping area.
37 // This is is hack until we implement SetGlobalClippingRectangle() (the opposite of SetGlobalClippingRectangle).
38+ GraphicsEngine& graphics_engine = GetWindowThread()->GetGraphicsEngine();
39+ unsigned int window_width = graphics_engine.GetWindowWidth();
40+ unsigned int window_height = graphics_engine.GetWindowHeight();
41 GetGraphicsDisplay()->GetGpuDevice()->DeactivateFrameBuffer();
42- GetWindowThread()->GetGraphicsEngine().SetViewport(0, 0,
43- GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(),
44- GetWindowThread ()->GetGraphicsEngine().GetWindowHeight());
45- GetWindowThread()->GetGraphicsEngine().EmptyClippingRegion ();
46-
47- Geometry global_clip_rect = GetWindowThread ()->GetGraphicsEngine().GetScissorRect();
48-
49-
50- global_clip_rect.y = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight() - global_clip_rect.y - global_clip_rect.height;
51-
52- // Raw the windows from back to front;
53- WindowList::reverse_iterator rev_it;
54-
55- for (rev_it = WindowList.rbegin (); rev_it != WindowList.rend (); rev_it++)
56+ graphics_engine.SetViewport(0, 0, window_width, window_height);
57+ graphics_engine.EmptyClippingRegion();
58+
59+ Geometry global_clip_rect = graphics_engine.GetScissorRect();
60+ global_clip_rect.y = window_height - global_clip_rect.y - global_clip_rect.height;
61+
62+ // Always make a copy of the windows to render. We have no control over
63+ // the windows we are actually drawing. It has been observed that some
64+ // windows modify the windows stack during the draw process.
65+ //
66+ // So... we take a copy of the window list. As much as I'd love to just
67+ // have BaseWindow* in the container, again, we have no control over the
68+ // windows we are drawing and one may just decide to unregister or destroy
69+ // another window mid-render. Since we are contructing a copy of the
70+ // list, lets reverse it as we are constructing, as we want to draw the
71+ // windows from back to front.
72+ WindowList windows(windows_to_render.rbegin(), windows_to_render.rend());
73+ for (WindowList::iterator it = windows.begin(), end = windows.end(); it != end; ++it)
74 {
75- if (!(*rev_it).IsValid())
76- continue;
77-
78- if ((drawModal == false) && (*rev_it)->IsModal())
79- continue;
80-
81-
82- if ((*rev_it)->IsVisible())
83+ WeakBaseWindowPtr& window_ptr = *it;
84+ if (window_ptr.IsNull())
85+ continue;
86+
87+ BaseWindow* window = window_ptr.GetPointer();
88+ if (!drawModal && window->IsModal())
89+ continue;
90+
91+ if (window->IsVisible())
92 {
93- if (global_clip_rect.Intersect((*rev_it)->GetGeometry()).IsNull())
94+ if (global_clip_rect.Intersect(window->GetGeometry()).IsNull())
95 {
96- // The global clipping area can be seen as a per monitor clipping region. It is mostly used in
97- // embedded mode with compiz.
98- // If we get here, it means that the BaseWindow we want to render is not in area of the monitor
99- // that compiz is currently rendering. So skip it.
100+ // The global clipping area can be seen as a per monitor clipping
101+ // region. It is mostly used in embedded mode with compiz. If we
102+ // get here, it means that the BaseWindow we want to render is not
103+ // in area of the monitor that compiz is currently rendering. So
104+ // skip it.
105 continue;
106 }
107-
108- RenderTargetTextures &rt = GetWindowBuffer((*rev_it).GetPointer());
109- BaseWindow *window = (*rev_it).GetPointer();
110-
111- // Based on the areas that requested a rendering inside the BaseWindow, render the BaseWindow or just use its cache.
112+
113+ RenderTargetTextures& rt = GetWindowBuffer(window);
114+
115+ // Based on the areas that requested a rendering inside the
116+ // BaseWindow, render the BaseWindow or just use its cache.
117 if (force_draw || window->IsRedrawNeeded() || window->ChildNeedsRedraw())
118 {
119 if (rt.color_rt.IsValid() /*&& rt.depth_rt.IsValid()*/)
120@@ -1445,7 +1455,8 @@
121 t_s32 buffer_width = window->GetBaseWidth();
122 t_s32 buffer_height = window->GetBaseHeight();
123
124- if ((rt.color_rt->GetWidth() != buffer_width) || (rt.color_rt->GetHeight() != buffer_height))
125+ if ((rt.color_rt->GetWidth() != buffer_width) ||
126+ (rt.color_rt->GetHeight() != buffer_height))
127 {
128 rt.color_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_R8G8B8A8);
129 rt.depth_rt = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (buffer_width, buffer_height, 1, BITFMT_D24S8);
130@@ -1455,11 +1466,11 @@
131 m_FrameBufferObject->SetRenderTarget ( 0, rt.color_rt->GetSurfaceLevel (0) );
132 m_FrameBufferObject->SetDepthSurface ( rt.depth_rt->GetSurfaceLevel (0) );
133 m_FrameBufferObject->Activate();
134- GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, buffer_width, buffer_height);
135- GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (buffer_width, buffer_height);
136- GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
137+ graphics_engine.SetViewport(0, 0, buffer_width, buffer_height);
138+ graphics_engine.SetOrthographicProjectionMatrix(buffer_width, buffer_height);
139+ graphics_engine.EmptyClippingRegion();
140
141- GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, buffer_width, buffer_height);
142+ graphics_engine.SetOpenGLClippingRectangle(0, 0, buffer_width, buffer_height);
143
144 CHECKGL ( glClearColor (0, 0, 0, 0) );
145 GLuint clear_color_buffer_bit = (force_draw || window->IsRedrawNeeded() ) ? GL_COLOR_BUFFER_BIT : 0;
146@@ -1471,36 +1482,31 @@
147 int y = window->GetBaseY();
148 Matrix4 mat;
149 mat.Translate (x, y, 0);
150- GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(),
151- GetWindowThread ()->GetGraphicsEngine().GetWindowHeight() );
152-
153- //GetWindowThread ()->GetGraphicsEngine().Push2DModelViewMatrix(mat);
154+ graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height);
155 }
156
157- RenderTopViewContent (/*fbo,*/ window, force_draw);
158+ RenderTopViewContent(window, force_draw);
159 }
160-
161- if (rt.color_rt.IsValid() /*&& rt.depth_rt.IsValid()*/)
162+
163+ if (rt.color_rt.IsValid())
164 {
165- // GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
166 m_FrameBufferObject->Deactivate();
167
168 // Enable this to render the drop shadow under windows: not perfect yet...
169 if (0)
170 {
171- unsigned int window_width, window_height;
172- window_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth();
173- window_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight();
174- GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion();
175- GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, window_width, window_height);
176- GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, window_width, window_height);
177- GetWindowThread ()->GetGraphicsEngine().SetOrthographicProjectionMatrix (window_width, window_height);
178+ graphics_engine.EmptyClippingRegion();
179+ graphics_engine.SetOpenGLClippingRectangle(0, 0, window_width, window_height);
180+ graphics_engine.SetViewport(0, 0, window_width, window_height);
181+ graphics_engine.SetOrthographicProjectionMatrix(window_width, window_height);
182
183- Geometry shadow (window->GetBaseX(), window->GetBaseY(), window->GetBaseWidth(), window->GetBaseHeight() );
184+ Geometry shadow(window->GetBaseX(), window->GetBaseY(),
185+ window->GetBaseWidth(), window->GetBaseHeight());
186 //if(window->IsVisibleSizeGrip())
187 {
188 shadow.OffsetPosition (4, 4);
189- GetPainter().PaintShape (GetWindowThread ()->GetGraphicsEngine(), shadow, Color (0xFF000000), eSHAPE_CORNER_SHADOW);
190+ GetPainter().PaintShape (graphics_engine, shadow, color::Black,
191+ eSHAPE_CORNER_SHADOW);
192 }
193 // else
194 // {
195@@ -1511,29 +1517,20 @@
196
197 CHECKGL ( glDepthMask (GL_FALSE) );
198 {
199- GetWindowThread ()->GetGraphicsEngine().ApplyClippingRectangle();
200+ graphics_engine.ApplyClippingRectangle();
201 PresentBufferToScreen (rt.color_rt, window->GetBaseX(), window->GetBaseY(), false, false, window->GetOpacity (), window->premultiply());
202 }
203 CHECKGL ( glDepthMask (GL_TRUE) );
204- GetWindowThread ()->GetGraphicsEngine().GetRenderStates().SetBlend (false);
205- }
206- else
207- {
208-// int x = window->GetX();
209-// int y = window->GetY();
210-// Matrix4 mat;
211-// mat.Translate(x, y, 0);
212- //GetWindowThread ()->GetGraphicsEngine().SetContext (0, 0, 0, 0);
213- //GetWindowThread ()->GetGraphicsEngine().Pop2DModelViewMatrix();
214- }
215-
216+ graphics_engine.GetRenderStates().SetBlend(false);
217+ }
218+
219 window->_child_need_redraw = false;
220 }
221 else
222 {
223- ObjectWeakPtr<BaseWindow> window = *rev_it;
224+ // Invisible window, nothing to draw.
225 window->_child_need_redraw = false;
226- window->DoneRedraw ();
227+ window->DoneRedraw();
228 }
229 }
230

Subscribers

People subscribed via source and target branches