Merge lp:~3v1n0/unity/massif-textures-sharing into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3289
Proposed branch: lp:~3v1n0/unity/massif-textures-sharing
Merge into: lp:unity
Diff against target: 672 lines (+133/-150)
12 files modified
launcher/Launcher.cpp (+2/-6)
panel/PanelView.cpp (+21/-24)
panel/PanelView.h (+1/-1)
plugins/unityshell/src/unityshell.cpp (+32/-53)
plugins/unityshell/src/unityshell.h (+2/-6)
tests/test_texture_cache.cpp (+3/-3)
unity-shared/DashStyle.cpp (+3/-13)
unity-shared/PanelStyle.cpp (+41/-19)
unity-shared/PanelStyle.h (+2/-1)
unity-shared/TextureCache.cpp (+17/-18)
unity-shared/TextureCache.h (+6/-4)
unity-shared/WindowButtons.cpp (+3/-2)
To merge this branch: bzr merge lp:~3v1n0/unity/massif-textures-sharing
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+157774@code.launchpad.net

Commit message

Unity: share textures whenever possible, optimize memory usage.

And some code improvements in TextureCache, PanelStyle, PanelView and unityshell

Description of the change

I've run unity under valgrind's massif, and I've noticed (as expected) that the most of the unity memory is used by textures. However, massif also underlined that we were allocating some resources many times (especially when in multi-monitor).

So, I've moved many components to use TextureCache, including PanelView, DashStyle, WindowButtons.

Improved a little the code of TextureCache that now has a default factory function to fetch textures from the default unity location.

Improvements in the PanelView background texture (that was used also by unityshell to paint the "fake" panel under the dash, in case of maximized windows): before we were generating real-size textures (and in case of unityshell big as the entire screen, a problem especially in case of multi-monitor), now we only generate 1x24 px texture that is repeated when drawing.

A not-scientific comparison of massif: http://ubuntuone.com/3NFLnQxLhIuBYziH0GKUfJ
In that tests I've ran unity for 5 minutes in my machine performing some basic unity operations using AP tests. It underlines ~5MB saving, it won't change the world but it's still a win! :)

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

494 glib::Object<GtkStyleContext> _style_context;
495 glib::Object<GSettings> _gsettings;
496 + BaseTexturePtr _bg_texture;
497 std::string _theme_name;
498 nux::Color _text_color;

Someday the naming of these variables will have to be fixed :)

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Looks good to me, tests pass and I don't see any black textures anywhere :)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/Launcher.cpp'
2--- launcher/Launcher.cpp 2013-04-05 19:20:49 +0000
3+++ launcher/Launcher.cpp 2013-04-09 01:09:21 +0000
4@@ -198,12 +198,8 @@
5 icon_renderer->SetTargetSize(_icon_size, _icon_image_size, _space_between_icons);
6
7 TextureCache& cache = TextureCache::GetDefault();
8- TextureCache::CreateTextureCallback cb = [&](std::string const& name, int width, int height) {
9- return nux::CreateTexture2DFromFile((PKGDATADIR"/" + name + ".png").c_str(), -1, true);
10- };
11-
12- launcher_sheen_ = cache.FindTexture("dash_sheen", 0, 0, cb);
13- launcher_pressure_effect_ = cache.FindTexture("launcher_pressure_effect", 0, 0, cb);
14+ launcher_sheen_ = cache.FindTexture("dash_sheen.png");
15+ launcher_pressure_effect_ = cache.FindTexture("launcher_pressure_effect.png");
16
17 options.changed.connect(sigc::mem_fun(this, &Launcher::OnOptionsChanged));
18 monitor.changed.connect(sigc::mem_fun(this, &Launcher::OnMonitorChanged));
19
20=== modified file 'panel/PanelView.cpp'
21--- panel/PanelView.cpp 2013-03-19 18:47:01 +0000
22+++ panel/PanelView.cpp 2013-04-09 01:09:21 +0000
23@@ -25,7 +25,6 @@
24 #include <Nux/WindowCompositor.h>
25
26 #include <NuxGraphics/CairoGraphics.h>
27-#include <NuxGraphics/ImageSurface.h>
28 #include <NuxCore/Logger.h>
29 #include <UnityCore/GLibWrapper.h>
30
31@@ -35,6 +34,7 @@
32 #include <glib.h>
33
34 #include "unity-shared/PanelStyle.h"
35+#include "unity-shared/TextureCache.h"
36 #include "unity-shared/WindowManager.h"
37 #include "unity-shared/UBusMessages.h"
38 #include <UnityCore/Variant.h>
39@@ -128,9 +128,10 @@
40 bg_effect_helper_.owner = this;
41
42 //FIXME (gord)- replace with async loading
43- panel_sheen_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/dash_sheen.png", -1, true));
44- bg_refine_tex_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/refine_gradient_panel.png", -1, true));
45- bg_refine_single_column_tex_.Adopt(nux::CreateTexture2DFromFile(PKGDATADIR"/refine_gradient_panel_single_column.png", -1, true));
46+ TextureCache& cache = TextureCache::GetDefault();
47+ panel_sheen_ = cache.FindTexture("dash_sheen.png");
48+ bg_refine_tex_ = cache.FindTexture("refine_gradient_panel.png");
49+ bg_refine_single_column_tex_ = cache.FindTexture("refine_gradient_panel_single_column.png");
50
51 rop.Blend = true;
52 rop.SrcBlend = GL_ONE;
53@@ -188,7 +189,8 @@
54 bg_color_.blue = blue;
55 bg_color_.alpha = alpha;
56
57- ForceUpdateBackground();
58+ if (overlay_is_open_)
59+ ForceUpdateBackground();
60 }
61
62 void PanelView::OnOverlayHidden(GVariant* data)
63@@ -267,7 +269,7 @@
64
65 GfxContext.PushClippingRectangle(geo);
66
67- if ((overlay_is_open_ || (opacity_ != 1.0f && opacity_ != 0.0f)))
68+ if (IsTransparent())
69 {
70 nux::Geometry const& geo_absolute = GetAbsoluteGeometry();
71 nux::Geometry blur_geo(geo_absolute.x, geo_absolute.y, geo.width, geo.height);
72@@ -281,7 +283,7 @@
73 bg_blur_texture_ = bg_effect_helper_.GetRegion(blur_geo);
74 }
75
76- if (bg_blur_texture_.IsValid() && (overlay_is_open_ || opacity_ != 1.0f))
77+ if (bg_blur_texture_.IsValid())
78 {
79 nux::TexCoordXForm texxform_blur_bg;
80 texxform_blur_bg.flip_v_coord = true;
81@@ -371,8 +373,7 @@
82 GfxContext.GetRenderStates().SetBlend(true);
83 GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
84
85- if (bg_blur_texture_.IsValid() &&
86- (overlay_is_open_ || (opacity_ != 1.0f && opacity_ != 0.0f)))
87+ if (bg_blur_texture_.IsValid() && IsTransparent())
88 {
89 nux::Geometry const& geo_absolute = GetAbsoluteGeometry();
90 nux::TexCoordXForm texxform_blur_bg;
91@@ -482,12 +483,9 @@
92 void
93 PanelView::UpdateBackground()
94 {
95- nux::Geometry const& geo = GetGeometry();
96-
97- if (!is_dirty_ && geo == last_geo_)
98+ if (!is_dirty_)
99 return;
100
101- last_geo_ = geo;
102 is_dirty_ = false;
103
104 nux::ROPConfig rop;
105@@ -512,13 +510,13 @@
106 opacity = 1.0f;
107 }
108
109- auto tex = panel::Style::Instance().GetBackground(geo.width, geo.height, opacity);
110+ auto const& tex = panel::Style::Instance().GetBackground();
111 nux::TexCoordXForm texxform;
112 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
113- texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
114+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
115
116 bg_layer_.reset(new nux::TextureLayer(tex->GetDeviceTexture(), texxform,
117- nux::color::White, true, rop));
118+ nux::color::White * opacity, true, rop));
119 }
120 }
121
122@@ -527,12 +525,6 @@
123 is_dirty_ = true;
124 UpdateBackground();
125
126- indicators_->QueueDraw();
127- tray_->QueueDraw();
128-
129- if (!overlay_is_open_)
130- menu_view_->QueueDraw();
131-
132 QueueDraw();
133 }
134
135@@ -703,12 +695,17 @@
136 if (opacity_ == opacity)
137 return;
138
139- opacity_ = opacity;
140- bg_effect_helper_.enabled = (opacity_ < 1.0f || overlay_is_open_);
141+ opacity_ = (opacity <= 0.0f ? 0.0001f : opacity); // Not to get a black menu area
142+ bg_effect_helper_.enabled = IsTransparent();
143
144 ForceUpdateBackground();
145 }
146
147+bool PanelView::IsTransparent()
148+{
149+ return (opacity_ < 1.0f || overlay_is_open_);
150+}
151+
152 void PanelView::SetMenuShowTimings(int fadein, int fadeout, int discovery,
153 int discovery_fadein, int discovery_fadeout)
154 {
155
156=== modified file 'panel/PanelView.h'
157--- panel/PanelView.h 2013-03-04 23:56:40 +0000
158+++ panel/PanelView.h 2013-04-09 01:09:21 +0000
159@@ -91,6 +91,7 @@
160 void OnOverlayShown(GVariant *data);
161 void OnOverlayHidden(GVariant *data);
162
163+ bool IsTransparent();
164 void UpdateBackground();
165 void ForceUpdateBackground();
166 bool TrackMenuPointer();
167@@ -116,7 +117,6 @@
168 BaseTexturePtr bg_refine_single_column_tex_;
169 std::unique_ptr<nux::AbstractPaintLayer> bg_refine_single_column_layer_;
170
171- nux::Geometry last_geo_;
172 nux::Color bg_color_;
173 std::string active_overlay_;
174 nux::Point tracked_pointer_pos_;
175
176=== modified file 'plugins/unityshell/src/unityshell.cpp'
177--- plugins/unityshell/src/unityshell.cpp 2013-03-29 13:59:11 +0000
178+++ plugins/unityshell/src/unityshell.cpp 2013-04-09 01:09:21 +0000
179@@ -146,8 +146,7 @@
180 , last_scroll_event_(0)
181 , hud_keypress_time_(0)
182 , first_menu_keypress_time_(0)
183- , panel_texture_has_changed_(true)
184- , paint_panel_(false)
185+ , paint_panel_under_dash_(false)
186 , scale_just_activated_(false)
187 , big_tick_(0)
188 , screen_introspection_(screen)
189@@ -705,8 +704,6 @@
190
191 void UnityScreen::OnPanelStyleChanged()
192 {
193- panel_texture_has_changed_ = true;
194-
195 // Reload the windows themed textures
196 UnityWindow::CleanupSharedTextures();
197
198@@ -723,7 +720,7 @@
199 {
200 CompOutput *output = _last_output;
201
202- DrawTopPanelBackground();
203+ DrawPanelUnderDash();
204
205 auto gpu_device = nux::GetGraphicsDisplay()->GetGpuDevice();
206
207@@ -809,45 +806,29 @@
208 didShellRepaint = true;
209 }
210
211-void UnityScreen::DrawTopPanelBackground()
212+void UnityScreen::DrawPanelUnderDash()
213 {
214+ if (!paint_panel_under_dash_ || !launcher_controller_->IsOverlayOpen())
215+ return;
216+
217+ if (_last_output->id() != screen->currentOutputDev().id())
218+ return;
219+
220 auto graphics_engine = nux::GetGraphicsDisplay()->GetGraphicsEngine();
221
222- if (!graphics_engine->UsingGLSLCodePath() || !launcher_controller_->IsOverlayOpen() || !paint_panel_)
223- return;
224-
225- if (TopPanelBackgroundTextureNeedsUpdate())
226- UpdateTopPanelBackgroundTexture();
227-
228- if (panel_texture_.IsValid())
229- {
230- graphics_engine->ResetModelViewMatrixStack();
231- graphics_engine->Push2DTranslationModelViewMatrix(0.0f, 0.0f, 0.0f);
232- graphics_engine->ResetProjectionMatrix();
233- graphics_engine->SetOrthographicProjectionMatrix(screen->width (), screen->height());
234-
235- nux::TexCoordXForm texxform;
236- int panel_height = panel_style_.panel_height;
237- graphics_engine->QRP_GLSL_1Tex(0, 0, screen->width (), panel_height, panel_texture_, texxform, nux::color::White);
238- }
239-}
240-
241-bool UnityScreen::TopPanelBackgroundTextureNeedsUpdate() const
242-{
243- return panel_texture_has_changed_ || !panel_texture_.IsValid();
244-}
245-
246-void UnityScreen::UpdateTopPanelBackgroundTexture()
247-{
248- auto &panel_style = panel::Style::Instance();
249-
250- panel_texture_.Release();
251- auto texture = panel_style.GetBackground(screen->width(), screen->height(), 1.0f);
252-
253- if (texture)
254- panel_texture_ = texture->GetDeviceTexture();
255-
256- panel_texture_has_changed_ = false;
257+ if (!graphics_engine->UsingGLSLCodePath())
258+ return;
259+
260+ graphics_engine->ResetModelViewMatrixStack();
261+ graphics_engine->Push2DTranslationModelViewMatrix(0.0f, 0.0f, 0.0f);
262+ graphics_engine->ResetProjectionMatrix();
263+ graphics_engine->SetOrthographicProjectionMatrix(screen->width(), screen->height());
264+
265+ nux::TexCoordXForm texxform;
266+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
267+ int panel_height = panel_style_.panel_height;
268+ auto const& texture = panel_style_.GetBackground()->GetDeviceTexture();
269+ graphics_engine->QRP_GLSL_1Tex(0, 0, screen->width(), panel_height, texture, texxform, nux::color::White);
270 }
271
272 bool UnityScreen::forcePaintOnTop ()
273@@ -1256,7 +1237,7 @@
274
275 allowWindowPaint = true;
276 _last_output = output;
277- paint_panel_ = false;
278+ paint_panel_under_dash_ = false;
279
280 // CompRegion has no clear() method. So this is the fastest alternative.
281 fullscreenRegion = CompRegion();
282@@ -2597,19 +2578,17 @@
283 const CompRegion& region,
284 unsigned int mask)
285 {
286- if (uScreen->doShellRepaint && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask)
287+ if (uScreen->doShellRepaint && !uScreen->paint_panel_under_dash_ && window->type() == CompWindowTypeNormalMask)
288 {
289- guint32 id = window->id();
290- bool maximized = WindowManager::Default().IsWindowMaximized(id);
291- bool on_current = window->onCurrentDesktop();
292- bool override_redirect = window->overrideRedirect();
293- bool managed = window->managed();
294- CompPoint viewport = window->defaultViewport();
295- int output = window->outputDevice();
296-
297- if (maximized && on_current && !override_redirect && managed && viewport == uScreen->screen->vp() && output == (int)uScreen->screen->currentOutputDev().id())
298+ if ((window->state() & MAXIMIZE_STATE) && window->onCurrentDesktop() && !window->overrideRedirect() && window->managed())
299 {
300- uScreen->paint_panel_ = true;
301+ CompPoint const& viewport = window->defaultViewport();
302+ unsigned output = window->outputDevice();
303+
304+ if (viewport == uScreen->screen->vp() && output == uScreen->screen->currentOutputDev().id())
305+ {
306+ uScreen->paint_panel_under_dash_ = true;
307+ }
308 }
309 }
310
311
312=== modified file 'plugins/unityshell/src/unityshell.h'
313--- plugins/unityshell/src/unityshell.h 2013-03-11 17:46:46 +0000
314+++ plugins/unityshell/src/unityshell.h 2013-04-09 01:09:21 +0000
315@@ -243,9 +243,7 @@
316
317 void InitGesturesSupport();
318
319- void DrawTopPanelBackground();
320- bool TopPanelBackgroundTextureNeedsUpdate() const;
321- void UpdateTopPanelBackgroundTexture();
322+ void DrawPanelUnderDash();
323
324 unsigned CompizModifiersToNux(unsigned input) const;
325 unsigned XModifiersToNux(unsigned input) const;
326@@ -331,9 +329,7 @@
327
328 GLMatrix panel_shadow_matrix_;
329
330- bool panel_texture_has_changed_;
331- bool paint_panel_;
332- nux::ObjectPtr<nux::IOpenGLBaseTexture> panel_texture_;
333+ bool paint_panel_under_dash_;
334 std::set<UnityWindow*> fake_decorated_windows_;
335
336 bool scale_just_activated_;
337
338=== modified file 'tests/test_texture_cache.cpp'
339--- tests/test_texture_cache.cpp 2011-09-02 02:24:56 +0000
340+++ tests/test_texture_cache.cpp 2013-04-09 01:09:21 +0000
341@@ -50,7 +50,7 @@
342 }
343 };
344
345-TEST(TestTextureCache, DISABLED_TestCallsCreateTextureCallback)
346+TEST(TestTextureCache, TestCallsCreateTextureCallback)
347 {
348 // Another lambda issue. If the lambda takes a reference to any other
349 // variables, it seems incapable of assigning the function to the
350@@ -80,7 +80,7 @@
351 }
352 };
353
354-TEST(TestTextureCache, DISABLED_TestCallbackOnlyCalledOnce)
355+TEST(TestTextureCache, TestCallbackOnlyCalledOnce)
356 {
357 TextureCallbackCounter counter;
358 TextureCache::CreateTextureCallback callback(sigc::mem_fun(counter, &TextureCallbackCounter::callback));
359@@ -95,7 +95,7 @@
360 EXPECT_TRUE(t1 == t2);
361 }
362
363-TEST(TestTextureCache, DISABLED_TestCacheRemovesDeletedObject)
364+TEST(TestTextureCache, TestCacheRemovesDeletedObject)
365 {
366 // Note for others, if just using the lambda function, the return value is
367 // lost in the type deduction that sigc uses. So we have the typedef
368
369=== modified file 'unity-shared/DashStyle.cpp'
370--- unity-shared/DashStyle.cpp 2013-03-11 22:18:58 +0000
371+++ unity-shared/DashStyle.cpp 2013-04-09 01:09:21 +0000
372@@ -42,6 +42,7 @@
373
374 #include "CairoTexture.h"
375 #include "JSONParser.h"
376+#include "TextureCache.h"
377 #include "UnitySettings.h"
378 #include "config.h"
379
380@@ -2547,19 +2548,8 @@
381
382 void LazyLoadTexture::LoadTexture()
383 {
384- std::string full_path = PKGDATADIR + filename_;
385- glib::Object<GdkPixbuf> pixbuf;
386- glib::Error error;
387-
388- pixbuf = ::gdk_pixbuf_new_from_file_at_size(full_path.c_str(), size_, size_, &error);
389- if (error)
390- {
391- LOG_WARN(logger) << "Unable to texture " << full_path << ": " << error;
392- }
393- else
394- {
395- texture_.Adopt(nux::CreateTexture2DFromPixbuf(pixbuf, true));
396- }
397+ TextureCache& cache = TextureCache::GetDefault();
398+ texture_ = cache.FindTexture(filename_, size_, size_);
399 }
400
401 } // anon namespace
402
403=== modified file 'unity-shared/PanelStyle.cpp'
404--- unity-shared/PanelStyle.cpp 2012-12-14 15:17:24 +0000
405+++ unity-shared/PanelStyle.cpp 2013-04-09 01:09:21 +0000
406@@ -34,6 +34,7 @@
407 #include "PanelStyle.h"
408
409 #include <UnityCore/GLibWrapper.h>
410+#include "unity-shared/TextureCache.h"
411 #include "unity-shared/UnitySettings.h"
412
413 namespace unity
414@@ -138,7 +139,7 @@
415 GdkRGBA rgba_text_color;
416 glib::String theme_name;
417 bool updated = false;
418-
419+
420 GtkSettings* settings = gtk_settings_get_default();
421 g_object_get(settings, "gtk-theme-name", &theme_name, nullptr);
422
423@@ -159,7 +160,10 @@
424 }
425
426 if (updated)
427+ {
428+ _bg_texture.Release();
429 changed.emit();
430+ }
431 }
432
433 GtkStyleContext* Style::GetStyleContext()
434@@ -167,8 +171,14 @@
435 return _style_context;
436 }
437
438-BaseTexturePtr Style::GetBackground(int width, int height, float opacity)
439+BaseTexturePtr Style::GetBackground()
440 {
441+ if (_bg_texture)
442+ return _bg_texture;
443+
444+ int width = 1;
445+ int height = panel_height();
446+
447 nux::CairoGraphics context(CAIRO_FORMAT_ARGB32, width, height);
448
449 // Use the internal context as we know it is good and shiny new.
450@@ -177,9 +187,11 @@
451 gtk_render_background(_style_context, cr, 0, 0, width, height);
452 gtk_render_frame(_style_context, cr, 0, 0, width, height);
453 cairo_pop_group_to_source(cr);
454- cairo_paint_with_alpha(cr, opacity);
455-
456- return texture_ptr_from_cairo_graphics(context);
457+ cairo_paint(cr);
458+
459+ _bg_texture = texture_ptr_from_cairo_graphics(context);
460+
461+ return _bg_texture;
462 }
463
464 /*!
465@@ -222,20 +234,30 @@
466
467 BaseTexturePtr Style::GetWindowButton(WindowButtonType type, WindowState state)
468 {
469- BaseTexturePtr texture;
470-
471- for (auto const& file : GetWindowButtonFileNames(type, state))
472- {
473- texture.Adopt(nux::CreateTexture2DFromFile(file.c_str(), -1, true));
474-
475- if (texture)
476- break;
477- }
478-
479- if (!texture)
480- texture = GetFallbackWindowButton(type, state);
481-
482- return texture;
483+ auto texture_factory = [this, type, state] (std::string const&, int, int) {
484+ nux::BaseTexture* texture = nullptr;
485+
486+ for (auto const& file : GetWindowButtonFileNames(type, state))
487+ {
488+ texture = nux::CreateTexture2DFromFile(file.c_str(), -1, true);
489+
490+ if (texture)
491+ return texture;
492+ }
493+
494+ auto const& fallback = GetFallbackWindowButton(type, state);
495+ texture = fallback.GetPointer();
496+ texture->Reference();
497+
498+ return texture;
499+ };
500+
501+ auto& cache = TextureCache::GetDefault();
502+ std::string texture_id = "window-button-";
503+ texture_id += std::to_string(static_cast<int>(type));
504+ texture_id += std::to_string(static_cast<int>(state));
505+
506+ return cache.FindTexture(texture_id, 0, 0, texture_factory);
507 }
508
509 BaseTexturePtr Style::GetFallbackWindowButton(WindowButtonType type,
510
511=== modified file 'unity-shared/PanelStyle.h'
512--- unity-shared/PanelStyle.h 2012-12-14 14:41:16 +0000
513+++ unity-shared/PanelStyle.h 2013-04-09 01:09:21 +0000
514@@ -71,7 +71,7 @@
515 typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
516
517 GtkStyleContext* GetStyleContext();
518- BaseTexturePtr GetBackground(int width, int height, float opacity);
519+ BaseTexturePtr GetBackground();
520 BaseTexturePtr GetWindowButton(WindowButtonType type, WindowState state);
521 BaseTexturePtr GetFallbackWindowButton(WindowButtonType type, WindowState state);
522 std::vector<std::string> GetWindowButtonFileNames(WindowButtonType type, WindowState state);
523@@ -88,6 +88,7 @@
524
525 glib::Object<GtkStyleContext> _style_context;
526 glib::Object<GSettings> _gsettings;
527+ BaseTexturePtr _bg_texture;
528 std::string _theme_name;
529 nux::Color _text_color;
530
531
532=== modified file 'unity-shared/TextureCache.cpp'
533--- unity-shared/TextureCache.cpp 2012-10-29 09:34:54 +0000
534+++ unity-shared/TextureCache.cpp 2013-04-09 01:09:21 +0000
535@@ -22,25 +22,23 @@
536
537 #include <sstream>
538 #include <NuxCore/Logger.h>
539+#include "config.h"
540
541 namespace unity
542 {
543 DECLARE_LOGGER(logger, "unity.internal.texturecache");
544
545-TextureCache::TextureCache()
546-{
547-}
548-
549-TextureCache::~TextureCache()
550-{
551-}
552-
553 TextureCache& TextureCache::GetDefault()
554 {
555 static TextureCache instance;
556 return instance;
557 }
558
559+nux::BaseTexture* TextureCache::DefaultTexturesLoader(std::string const& name, int w, int h)
560+{
561+ return nux::CreateTexture2DFromFile((PKGDATADIR"/" + name).c_str(), -1, true);
562+}
563+
564 std::string TextureCache::Hash(std::string const& id, int width, int height)
565 {
566 std::ostringstream sout;
567@@ -50,17 +48,22 @@
568
569 TextureCache::BaseTexturePtr TextureCache::FindTexture(std::string const& texture_id,
570 int width, int height,
571- CreateTextureCallback slot)
572+ CreateTextureCallback factory)
573 {
574- if (!slot)
575+ if (!factory)
576 return BaseTexturePtr();
577
578- std::string key = Hash(texture_id, width, height);
579- BaseTexturePtr texture(cache_[key]);
580+ std::string const& key = Hash(texture_id, width, height);
581+ auto texture_it = cache_.find(key);
582+
583+ BaseTexturePtr texture(texture_it != cache_.end() ? texture_it->second : nullptr);
584
585 if (!texture)
586 {
587- texture = slot(texture_id, width, height);
588+ texture.Adopt(factory(texture_id, width, height));
589+
590+ if (!texture)
591+ return texture;
592
593 // Now here is the magic.
594 //
595@@ -79,10 +82,6 @@
596 // are destroyed first, then the sigc::trackable disconnects all methods
597 // created using mem_fun.
598
599- // Reduce the internal reference count of the texture, so the smart
600- // pointer is the sole owner of the object.
601- texture->UnReference();
602-
603 cache_[key] = texture.GetPointer();
604
605 auto on_destroy = sigc::mem_fun(this, &TextureCache::OnDestroyNotify);
606@@ -92,7 +91,7 @@
607 return texture;
608 }
609
610-void TextureCache::OnDestroyNotify(nux::Trackable* Object, std::string key)
611+void TextureCache::OnDestroyNotify(nux::Trackable* Object, std::string const& key)
612 {
613 cache_.erase(key);
614 }
615
616=== modified file 'unity-shared/TextureCache.h'
617--- unity-shared/TextureCache.h 2012-07-16 11:03:32 +0000
618+++ unity-shared/TextureCache.h 2013-04-09 01:09:21 +0000
619@@ -40,24 +40,26 @@
620 public:
621 typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr;
622
623+ ~TextureCache() = default;
624+
625 // id, width, height -> texture
626 typedef std::function<nux::BaseTexture*(std::string const&, int, int)> CreateTextureCallback;
627
628 static TextureCache& GetDefault();
629+ static nux::BaseTexture* DefaultTexturesLoader(std::string const&, int, int);
630
631- BaseTexturePtr FindTexture(std::string const& texture_id, int width, int height, CreateTextureCallback callback);
632+ BaseTexturePtr FindTexture(std::string const& texture_id, int width = 0, int height = 0, CreateTextureCallback callback = DefaultTexturesLoader);
633
634 // Return the current size of the cache.
635 std::size_t Size() const;
636
637 private:
638- TextureCache();
639- ~TextureCache();
640+ TextureCache() = default;
641
642 std::string Hash(std::string const& , int width, int height);
643 // Have the key passed by value not referece, as the key will be a bound
644 // parameter in the slot passed to the texture on_destroy signal.
645- void OnDestroyNotify(nux::Trackable* Object, std::string key);
646+ void OnDestroyNotify(nux::Trackable* Object, std::string const& key);
647
648 std::map<std::string, nux::BaseTexture*> cache_;
649 };
650
651=== modified file 'unity-shared/WindowButtons.cpp'
652--- unity-shared/WindowButtons.cpp 2013-03-19 18:47:01 +0000
653+++ unity-shared/WindowButtons.cpp 2013-04-09 01:09:21 +0000
654@@ -29,6 +29,7 @@
655 #include "WindowButtons.h"
656 #include "WindowButtonPriv.h"
657
658+#include "unity-shared/TextureCache.h"
659 #include "unity-shared/UBusMessages.h"
660 #include "unity-shared/WindowManager.h"
661
662@@ -176,8 +177,8 @@
663
664 std::string subpath = names[static_cast<int>(type)] + states[static_cast<int>(state)] + ".png";
665
666- glib::String filename(g_build_filename(PKGDATADIR, subpath.c_str(), NULL));
667- texture.Adopt(nux::CreateTexture2DFromFile(filename, -1, true));
668+ auto& cache = TextureCache::GetDefault();
669+ texture = cache.FindTexture(subpath);
670
671 if (!texture)
672 texture = panel::Style::Instance().GetFallbackWindowButton(type, state);