Merge lp:~widelands-dev/widelands/remove_in_memory_image into lp:widelands

Proposed by SirVer
Status: Merged
Merged at revision: 7318
Proposed branch: lp:~widelands-dev/widelands/remove_in_memory_image
Merge into: lp:widelands
Prerequisite: lp:~widelands-dev/widelands/remove_player_color
Diff against target: 519 lines (+54/-101)
22 files modified
src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc (+1/-1)
src/graphic/animation.cc (+5/-0)
src/graphic/animation.h (+1/-0)
src/graphic/font_handler.cc (+5/-6)
src/graphic/font_handler1.cc (+1/-2)
src/graphic/gl/road_program.cc (+2/-2)
src/graphic/graphic.cc (+1/-1)
src/graphic/image.h (+1/-3)
src/graphic/image_cache.cc (+11/-52)
src/graphic/image_cache.h (+7/-11)
src/graphic/image_io.cc (+2/-2)
src/graphic/image_io.h (+2/-1)
src/graphic/in_memory_image.cc (+4/-8)
src/graphic/in_memory_image.h (+2/-2)
src/graphic/minimap_renderer.cc (+1/-1)
src/graphic/surface.h (+1/-1)
src/graphic/text/test/render.cc (+1/-1)
src/logic/building.cc (+1/-1)
src/map_io/map_extradata_packet.cc (+2/-1)
src/scripting/lua_map.cc (+1/-2)
src/ui_fsmenu/loadgame.cc (+1/-2)
src/wui/minimap.cc (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/remove_in_memory_image
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+243911@code.launchpad.net

Description of the change

InMemoryImage and FromDiskImage are now the same thing, only richtext images are
special in any kind of way.

--
This is only a tiny cleanup, but I think it is useful and should go in. I need to experiment with the future direction I want to go, so I push this now for review.

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

2 comments to think about, otherwise LGTM.

review: Approve
Revision history for this message
SirVer (sirver) wrote :

> Should we check for g_fs->file_exists here?

No. We expect the images that are loaded here to be there and load_image will throw an error if they are not. If the callsite assumes that the picture is not there, it can catch the error and recover.

> Why not just return image.get() and do away with the extra variable? Unless image.get() has a side effect that we need for the insert.

It is not the image.get() that has side effects, but the std::move().

258 + images_.insert(make_pair(hash, std::move(image)));

unique_ptr means that there is always exactly one unique_ptr object that owns the underlying raw pointer, i.e. where get() != nullptr. This is necessary, so that the underlying object is deleted only once (when the owning unique_ptr goes out of scope).
std::move (or assignment) transfers the ownership from one unique_ptr to another, so in our case after calling insert(), image.get == nullptr. so we need to hold on to the pointer object before insert() since we have no way of getting to it after.

GunChleoc (gunchleoc) wrote 9 minutes ago:

Revision history for this message
SirVer (sirver) wrote :

Thanks for the review! gonna merge.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc'
2--- src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc 2014-12-04 09:00:20 +0000
3+++ src/editor/ui_menus/editor_tool_set_terrain_options_menu.cc 2014-12-10 05:19:53 +0000
4@@ -145,7 +145,7 @@
5 }
6
7 // Make sure we delete this later on.
8- offscreen_images->emplace_back(new_in_memory_image("dummy_hash", texture));
9+ offscreen_images->emplace_back(new_in_memory_image(texture));
10 break;
11 }
12 /** TRANSLATORS: %1% = terrain name, %2% = list of terrain types */
13
14=== modified file 'src/graphic/animation.cc'
15--- src/graphic/animation.cc 2014-12-06 16:17:06 +0000
16+++ src/graphic/animation.cc 2014-12-10 05:19:53 +0000
17@@ -127,6 +127,7 @@
18 uint32_t frametime() const override;
19 const Point& hotspot() const override;
20 const Image& representative_image_from_disk() const override;
21+ const std::string& representative_image_from_disk_filename() const override;
22 virtual void blit(uint32_t time, const Point&, const Rect& srcrc, const RGBColor* clr, Surface*)
23 const override;
24 void trigger_soundfx(uint32_t framenumber, uint32_t stereo_position) const override;
25@@ -302,6 +303,10 @@
26 return *frames_[0];
27 }
28
29+const std::string& NonPackedAnimation::representative_image_from_disk_filename() const {
30+ return image_files_[0];
31+}
32+
33 void NonPackedAnimation::trigger_soundfx(uint32_t time, uint32_t stereo_position) const {
34 if (sound_effect_.empty()) {
35 return;
36
37=== modified file 'src/graphic/animation.h'
38--- src/graphic/animation.h 2014-12-06 16:14:53 +0000
39+++ src/graphic/animation.h 2014-12-10 05:19:53 +0000
40@@ -72,6 +72,7 @@
41 // a clutch needed to make sure that messages can always be displayed, even
42 // no image processing has taken place before.
43 virtual const Image& representative_image_from_disk() const = 0;
44+ virtual const std::string& representative_image_from_disk_filename() const = 0;
45
46 /// Blit the animation frame that should be displayed at the given time index
47 /// so that the given point is at the top left of the frame. Srcrc defines
48
49=== modified file 'src/graphic/font_handler.cc'
50--- src/graphic/font_handler.cc 2014-11-24 07:10:03 +0000
51+++ src/graphic/font_handler.cc 2014-12-10 05:19:53 +0000
52@@ -22,6 +22,7 @@
53 #include "graphic/font_handler.h"
54
55 #include <list>
56+#include <memory>
57
58 #include <SDL_ttf.h>
59 #include <boost/algorithm/string.hpp>
60@@ -73,7 +74,7 @@
61 /*@}*/
62
63 /*@{*/
64- const Image* image;
65+ std::unique_ptr<const Image> image;
66 uint32_t width;
67 uint32_t height;
68 /*@}*/
69@@ -93,7 +94,6 @@
70
71 ~Data() {
72 while (!linecache.empty()) {
73- delete linecache.back().image;
74 linecache.pop_back();
75 }
76 }
77@@ -161,7 +161,6 @@
78 render_line(*it);
79
80 while (linecache.size() > MaxLineCacheSize) {
81- delete linecache.back().image;
82 linecache.pop_back();
83 }
84
85@@ -197,7 +196,7 @@
86 return;
87 }
88
89- lce.image = new_in_memory_image("dummy_hash", new Texture(text_surface));
90+ lce.image = new_in_memory_image(new Texture(text_surface));
91 lce.width = lce.image->width();
92 lce.height = lce.image->height();
93 }
94@@ -221,7 +220,7 @@
95 UI::correct_for_align(align, lce.width + 2 * LINE_MARGIN, lce.height, &dstpoint);
96
97 if (lce.image)
98- dst.blit(Point(dstpoint.x + LINE_MARGIN, dstpoint.y), lce.image);
99+ dst.blit(Point(dstpoint.x + LINE_MARGIN, dstpoint.y), lce.image.get());
100
101 if (caret <= copytext.size())
102 draw_caret(dst, style, dstpoint, copytext, caret);
103@@ -239,7 +238,7 @@
104 const LineCacheEntry & lce = d->get_line(style, text);
105
106 if (lce.image)
107- dst.blit(dstpoint, lce.image);
108+ dst.blit(dstpoint, lce.image.get());
109
110 return lce.width;
111 }
112
113=== modified file 'src/graphic/font_handler1.cc'
114--- src/graphic/font_handler1.cc 2014-11-24 07:12:35 +0000
115+++ src/graphic/font_handler1.cc 2014-12-10 05:19:53 +0000
116@@ -57,7 +57,6 @@
117 // Implements Image.
118 uint16_t width() const override {return texture()->width();}
119 uint16_t height() const override {return texture()->height();}
120- const string& hash() const override {return hash_;}
121 Texture* texture() const override {
122 Texture* surf = texture_cache_->get(hash_);
123 if (surf)
124@@ -100,7 +99,7 @@
125 std::unique_ptr<RTImage> image(new RTImage(hash, texture_cache_, renderer_.get(), text, w));
126 image->texture(); // force the rich text to get rendered in case there is an exception thrown.
127
128- return image_cache_->insert(image.release());
129+ return image_cache_->insert(hash, std::move(image));
130 }
131
132 private:
133
134=== modified file 'src/graphic/gl/road_program.cc'
135--- src/graphic/gl/road_program.cc 2014-11-24 07:10:03 +0000
136+++ src/graphic/gl/road_program.cc 2014-12-10 05:19:53 +0000
137@@ -87,8 +87,8 @@
138 u_normal_road_texture_ = glGetUniformLocation(gl_program_.object(), "u_normal_road_texture");
139 u_busy_road_texture_ = glGetUniformLocation(gl_program_.object(), "u_busy_road_texture");
140
141- normal_road_texture_.reset(load_image("world/pics/roadt_normal.png"));
142- busy_road_texture_.reset(load_image("world/pics/roadt_busy.png"));
143+ normal_road_texture_ = load_image("world/pics/roadt_normal.png");
144+ busy_road_texture_ = load_image("world/pics/roadt_busy.png");
145 }
146
147 RoadProgram::~RoadProgram() {
148
149=== modified file 'src/graphic/graphic.cc'
150--- src/graphic/graphic.cc 2014-12-08 07:40:12 +0000
151+++ src/graphic/graphic.cc 2014-12-10 05:19:53 +0000
152@@ -67,7 +67,7 @@
153 m_window_mode_height(window_mode_h),
154 m_update(true),
155 texture_cache_(create_texture_cache(TRANSIENT_TEXTURE_CACHE_SIZE)),
156- image_cache_(new ImageCache(texture_cache_.get())),
157+ image_cache_(new ImageCache()),
158 animation_manager_(new AnimationManager())
159 {
160 // Request an OpenGL 2 context with double buffering.
161
162=== modified file 'src/graphic/image.h'
163--- src/graphic/image.h 2014-11-24 07:10:03 +0000
164+++ src/graphic/image.h 2014-12-10 05:19:53 +0000
165@@ -39,11 +39,9 @@
166
167 virtual uint16_t width() const = 0;
168 virtual uint16_t height() const = 0;
169-
170- // Internal functions needed for caching.
171 virtual Texture* texture() const = 0;
172- virtual const std::string& hash() const = 0;
173
174+private:
175 DISALLOW_COPY_AND_ASSIGN(Image);
176 };
177
178
179=== modified file 'src/graphic/image_cache.cc'
180--- src/graphic/image_cache.cc 2014-11-24 07:10:03 +0000
181+++ src/graphic/image_cache.cc 2014-12-10 05:19:53 +0000
182@@ -20,78 +20,37 @@
183 #include "graphic/image_cache.h"
184
185 #include <cassert>
186+#include <memory>
187 #include <string>
188
189 #include "base/log.h"
190 #include "graphic/image.h"
191 #include "graphic/image_io.h"
192+#include "graphic/in_memory_image.h"
193 #include "graphic/texture.h"
194-#include "graphic/texture_cache.h"
195-
196-namespace {
197-
198-// Image Implementation that loads images from disc when they should be drawn.
199-// Uses TextureCache. These images are meant to be cached in ImageCache.
200-class FromDiskImage : public Image {
201-public:
202- FromDiskImage(const std::string& filename, TextureCache* texture_cache) :
203- filename_(filename),
204- texture_cache_(texture_cache) {
205- Texture* texture = reload_image_();
206- w_ = texture->width();
207- h_ = texture->height();
208- }
209- virtual ~FromDiskImage() {}
210-
211- // Implements Image.
212- uint16_t width() const override {return w_; }
213- uint16_t height() const override {return h_;}
214- const std::string& hash() const override {return filename_;}
215- Texture* texture() const override {
216- Texture* texture = texture_cache_->get(filename_);
217- if (texture)
218- return texture;
219- return reload_image_();
220- }
221-
222-private:
223- Texture* reload_image_() const {
224- Texture* texture = texture_cache_->insert(filename_, load_image(filename_), false);
225- return texture;
226- }
227- uint16_t w_, h_;
228- const std::string filename_;
229-
230- TextureCache* const texture_cache_; // Not owned.
231-};
232-
233-} // namespace
234-
235-ImageCache::ImageCache(TextureCache* const texture_cache) : texture_cache_(texture_cache) {
236+
237+ImageCache::ImageCache() {
238 }
239
240 ImageCache::~ImageCache() {
241- for (ImageMap::value_type& p : images_) {
242- delete p.second;
243- }
244- images_.clear();
245 }
246
247 bool ImageCache::has(const std::string& hash) const {
248 return images_.count(hash);
249 }
250
251-const Image* ImageCache::insert(const Image* image) {
252- assert(!has(image->hash()));
253- images_.insert(make_pair(image->hash(), image));
254- return image;
255+const Image* ImageCache::insert(const std::string& hash, std::unique_ptr<const Image> image) {
256+ assert(!has(hash));
257+ const Image* return_value = image.get();
258+ images_.insert(make_pair(hash, std::move(image)));
259+ return return_value;
260 }
261
262 const Image* ImageCache::get(const std::string& hash) {
263 ImageMap::const_iterator it = images_.find(hash);
264 if (it == images_.end()) {
265- images_.insert(make_pair(hash, new FromDiskImage(hash, texture_cache_)));
266+ images_.insert(make_pair(hash, new_in_memory_image(load_image(hash).release())));
267 return get(hash);
268 }
269- return it->second;
270+ return it->second.get();
271 }
272
273=== modified file 'src/graphic/image_cache.h'
274--- src/graphic/image_cache.h 2014-11-24 07:10:03 +0000
275+++ src/graphic/image_cache.h 2014-12-10 05:19:53 +0000
276@@ -20,16 +20,15 @@
277 #ifndef WL_GRAPHIC_IMAGE_CACHE_H
278 #define WL_GRAPHIC_IMAGE_CACHE_H
279
280+#include <map>
281+#include <memory>
282 #include <string>
283-#include <map>
284
285 #include <boost/utility.hpp>
286
287 #include "base/macros.h"
288 #include "graphic/image.h"
289
290-class TextureCache;
291-
292 // For historic reasons, most part of the Widelands code base expect that an
293 // Image stays valid for the whole duration of the program run. This class is
294 // the one that keeps ownership of all Images to ensure that this is true. Also
295@@ -39,14 +38,12 @@
296 // releasing their ownership.
297 class ImageCache {
298 public:
299- // Does not take ownership.
300- ImageCache(TextureCache* texture_cache);
301+ ImageCache();
302 ~ImageCache();
303
304- // Insert the given Image into the cache. The hash is defined by Image's hash()
305- // function. Ownership of the Image is taken. Will return a pointer to the freshly inserted
306- // image for convenience.
307- const Image* insert(const Image*);
308+ // Insert the given Image into the cache.
309+ // Will return a pointer to the freshly inserted image for convenience.
310+ const Image* insert(const std::string& hash, std::unique_ptr<const Image> image);
311
312 // Returns the image associated with the given hash. If no image by this
313 // hash is known, it will try to load one from disk with the filename =
314@@ -57,10 +54,9 @@
315 bool has(const std::string& hash) const;
316
317 private:
318- using ImageMap = std::map<std::string, const Image*>;
319+ using ImageMap = std::map<std::string, std::unique_ptr<const Image>>;
320
321 ImageMap images_; /// hash of cached filename/image pairs
322- TextureCache* const texture_cache_; // Not owned.
323
324 DISALLOW_COPY_AND_ASSIGN(ImageCache);
325 };
326
327=== modified file 'src/graphic/image_io.cc'
328--- src/graphic/image_io.cc 2014-12-03 07:39:19 +0000
329+++ src/graphic/image_io.cc 2014-12-10 05:19:53 +0000
330@@ -56,8 +56,8 @@
331
332 } // namespace
333
334-Texture* load_image(const std::string& fname, FileSystem* fs) {
335- return new Texture(load_image_as_sdl_surface(fname, fs));
336+std::unique_ptr<Texture> load_image(const std::string& fname, FileSystem* fs) {
337+ return std::unique_ptr<Texture>(new Texture(load_image_as_sdl_surface(fname, fs)));
338 }
339
340 SDL_Surface* load_image_as_sdl_surface(const std::string& fname, FileSystem* fs) {
341
342=== modified file 'src/graphic/image_io.h'
343--- src/graphic/image_io.h 2014-11-30 09:17:50 +0000
344+++ src/graphic/image_io.h 2014-12-10 05:19:53 +0000
345@@ -20,6 +20,7 @@
346 #ifndef WL_GRAPHIC_IMAGE_IO_H
347 #define WL_GRAPHIC_IMAGE_IO_H
348
349+#include <memory>
350 #include <string>
351
352 #include "base/wexception.h"
353@@ -45,7 +46,7 @@
354 };
355
356 /// Loads the image 'fn' from 'fs'.
357-Texture* load_image(const std::string& fn, FileSystem* fs = nullptr);
358+std::unique_ptr<Texture> load_image(const std::string& fn, FileSystem* fs = nullptr);
359
360 /// Loads the image 'fn' from 'fs' into an SDL_Surface. Caller must SDL_FreeSurface() the returned value.
361 SDL_Surface* load_image_as_sdl_surface(const std::string& fn, FileSystem* fs = nullptr);
362
363=== modified file 'src/graphic/in_memory_image.cc'
364--- src/graphic/in_memory_image.cc 2014-12-07 10:31:12 +0000
365+++ src/graphic/in_memory_image.cc 2014-12-10 05:19:53 +0000
366@@ -38,24 +38,20 @@
367 // or prepare for core dumps.
368 class InMemoryImage : public Image {
369 public:
370- InMemoryImage(const string& ghash, Texture* init_texture) :
371- hash_(ghash), texture_(init_texture) {}
372+ InMemoryImage(Texture* init_texture) :
373+ texture_(init_texture) {}
374 virtual ~InMemoryImage() {
375 }
376
377 // Implements Image.
378 uint16_t width() const override {return texture_->width();}
379 uint16_t height() const override {return texture_->height();}
380- // Note: hash will mostly be dummy values for this implementation. It should
381- // not wind up in ImageCache, otherwise the ownership question is not clear.
382- const string& hash() const override {return hash_;}
383 Texture* texture() const override {return texture_.get();}
384
385 private:
386- const string hash_;
387 std::unique_ptr<Texture> texture_;
388 };
389
390-const Image* new_in_memory_image(const string& hash, Texture* texture) {
391- return new InMemoryImage(hash, texture);
392+std::unique_ptr<const Image> new_in_memory_image(Texture* texture) {
393+ return std::unique_ptr<const Image>(new InMemoryImage(texture));
394 }
395
396=== modified file 'src/graphic/in_memory_image.h'
397--- src/graphic/in_memory_image.h 2014-11-24 07:10:03 +0000
398+++ src/graphic/in_memory_image.h 2014-12-10 05:19:53 +0000
399@@ -20,11 +20,11 @@
400 #ifndef WL_GRAPHIC_IN_MEMORY_IMAGE_H
401 #define WL_GRAPHIC_IN_MEMORY_IMAGE_H
402
403-#include <string>
404+#include <memory>
405
406 class Texture;
407 class Image;
408
409-const Image* new_in_memory_image(const std::string& hash, Texture* texture);
410+std::unique_ptr<const Image> new_in_memory_image(Texture* texture);
411
412 #endif // end of include guard: WL_GRAPHIC_IN_MEMORY_IMAGE_H
413
414=== modified file 'src/graphic/minimap_renderer.cc'
415--- src/graphic/minimap_renderer.cc 2014-11-27 21:29:21 +0000
416+++ src/graphic/minimap_renderer.cc 2014-12-10 05:19:53 +0000
417@@ -308,7 +308,7 @@
418
419 // Render minimap
420 std::unique_ptr<Texture> texture(draw_minimap(egbase, player, viewpoint, layers));
421- std::unique_ptr<const Image> image(new_in_memory_image("minimap", texture.release()));
422+ std::unique_ptr<const Image> image(new_in_memory_image(texture.release()));
423 g_gr->save_png(image.get(), streamwrite);
424 image.reset();
425 }
426
427=== modified file 'src/graphic/surface.h'
428--- src/graphic/surface.h 2014-12-06 15:34:53 +0000
429+++ src/graphic/surface.h 2014-12-10 05:19:53 +0000
430@@ -33,7 +33,7 @@
431 * Interface to a basic surfaces that can be used as destination for blitting and drawing.
432 * It also allows low level pixel access.
433 */
434-class Surface {
435+class Surface {
436 public:
437 Surface() = default;
438 virtual ~Surface() {}
439
440=== modified file 'src/graphic/text/test/render.cc'
441--- src/graphic/text/test/render.cc 2014-11-24 07:10:03 +0000
442+++ src/graphic/text/test/render.cc 2014-12-10 05:19:53 +0000
443@@ -36,7 +36,7 @@
444 g_fs->add_file_system(&FileSystem::create(RICHTEXT_DATA_DIR));
445
446 texture_cache_.reset(create_texture_cache(500 << 20)); // 500 MB
447- image_cache_.reset(new ImageCache(texture_cache_.get()));
448+ image_cache_.reset(new ImageCache());
449 renderer_.reset(new RT::Renderer(image_cache_.get(), texture_cache_.get()));
450 }
451
452
453=== modified file 'src/logic/building.cc'
454--- src/logic/building.cc 2014-11-30 18:49:38 +0000
455+++ src/logic/building.cc 2014-12-10 05:19:53 +0000
456@@ -889,7 +889,7 @@
457 // animations of buildings so that the messages can still be displayed, even
458 // after reload.
459 const std::string& img = g_gr->animations().get_animation
460- (get_ui_anim()).representative_image_from_disk().hash();
461+ (get_ui_anim()).representative_image_from_disk_filename();
462 std::string rt_description;
463 rt_description.reserve
464 (strlen("<rt image=") + img.size() + 1 +
465
466=== modified file 'src/map_io/map_extradata_packet.cc'
467--- src/map_io/map_extradata_packet.cc 2014-12-01 06:19:03 +0000
468+++ src/map_io/map_extradata_packet.cc 2014-12-10 05:19:53 +0000
469@@ -59,7 +59,8 @@
470 const std::string hash = std::string("map:") + FileSystem::fs_filename(pname->c_str());
471 const Image* image = nullptr;
472 if (!g_gr->images().has(hash)) {
473- image = g_gr->images().insert(new_in_memory_image(hash, load_image(*pname, &fs)));
474+ image = g_gr->images().insert(
475+ hash, new_in_memory_image(load_image(*pname, &fs).release()));
476 } else {
477 image = g_gr->images().get(hash);
478 }
479
480=== modified file 'src/scripting/lua_map.cc'
481--- src/scripting/lua_map.cc 2014-12-03 20:13:44 +0000
482+++ src/scripting/lua_map.cc 2014-12-10 05:19:53 +0000
483@@ -1097,8 +1097,7 @@
484 */
485 int LuaMapObjectDescription::get_representative_image(lua_State * L) {
486 const std::string& filepath = g_gr->animations().get_animation
487- (get()->get_animation("idle")).representative_image_from_disk().hash();
488-
489+ (get()->get_animation("idle")).representative_image_from_disk_filename();
490 lua_pushstring(L, filepath);
491 return 1;
492 }
493
494=== modified file 'src/ui_fsmenu/loadgame.cc'
495--- src/ui_fsmenu/loadgame.cc 2014-12-04 09:18:03 +0000
496+++ src/ui_fsmenu/loadgame.cc 2014-12-10 05:19:53 +0000
497@@ -321,8 +321,7 @@
498 minimap_path,
499 std::unique_ptr<FileSystem>(g_fs->make_sub_file_system(gamedata.filename)).get()));
500
501- m_minimap_image.reset(new_in_memory_image(std::string(gamedata.filename + minimap_path),
502- texture.release()));
503+ m_minimap_image = new_in_memory_image(texture.release());
504
505 // Scale it
506 double scale = double(m_minimap_w) / m_minimap_image->width();
507
508=== modified file 'src/wui/minimap.cc'
509--- src/wui/minimap.cc 2014-11-30 18:49:38 +0000
510+++ src/wui/minimap.cc 2014-12-10 05:19:53 +0000
511@@ -71,7 +71,7 @@
512 Point((m_viewx - get_w() / 2), (m_viewy - get_h() / 2)),
513 *m_flags | MiniMapLayer::ViewWindow));
514 // Give ownership of the texture to the new image
515- std::unique_ptr<const Image> im(new_in_memory_image("minimap", texture.release()));
516+ std::unique_ptr<const Image> im(new_in_memory_image(texture.release()));
517 dst.blit(Point(), im.get());
518 im.reset();
519 }

Subscribers

People subscribed via source and target branches

to status/vote changes: