ManaPlus
sdlcheckutils.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2013-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "utils/sdlcheckutils.h"
23 
24 #ifdef DEBUG_SDL_SURFACES
25 
26 #include "logger.h"
27 
28 #include "utils/sdlmemoryobject.h"
29 #include "utils/stringutils.h"
30 
31 #include <map>
32 
33 PRAGMA48(GCC diagnostic push)
34 PRAGMA48(GCC diagnostic ignored "-Wshadow")
35 #include <SDL_image.h>
36 #include <SDL_ttf.h>
37 PRAGMA48(GCC diagnostic pop)
38 
39 #include "debug.h"
40 
41 #define DEBUG_SURFACE_ALLOCATION 1
42 
43 std::map<void*, SDLMemoryObject*> mSurfaces;
44 
45 static SDL_Surface *addSurface(const char *restrict const name,
46  SDL_Surface *restrict const surface,
47  const char *restrict const file,
48  const unsigned line)
49 {
50 #ifdef DEBUG_SURFACE_ALLOCATION
51  logger->log("add surface: %s %s:%u %p", name,
52  file, line, static_cast<void*>(surface));
53 #endif // DEBUG_SURFACE_ALLOCATION
54 
55  std::map<void*, SDLMemoryObject*>::iterator
56  it = mSurfaces.find(surface);
57  if (it != mSurfaces.end())
58  {
59  SDLMemoryObject *const obj = (*it).second;
60  if (obj)
61  { // found some time ago created surface
62 #ifdef DEBUG_SURFACE_ALLOCATION
63  logger->log("adding existing surface: %p, count:%d\n"
64  "was add %s\nwas deleted %s", surface, obj->mCnt,
65  obj->mAddFile.c_str(), obj->mRemoveFile.c_str());
66 #endif // DEBUG_SURFACE_ALLOCATION
67 
68  obj->mCnt ++;
69  }
70  }
71  else
72  { // creating surface object
73  mSurfaces[surface] = new SDLMemoryObject(name, file, line);
74  }
75  return surface;
76 }
77 
78 static void deleteSurface(const char *restrict const name A_UNUSED,
79  SDL_Surface *restrict const surface,
80  const char *restrict const file,
81  const unsigned line)
82 {
83 #ifdef DEBUG_SURFACE_ALLOCATION
84  logger->log("delete surface: %s %s:%u %p", name, file, line, surface);
85 #endif // DEBUG_SURFACE_ALLOCATION
86 
87  std::map<void*, SDLMemoryObject*>::iterator
88  it = mSurfaces.find(surface);
89  if (it == mSurfaces.end())
90  {
91  logger->log("bad surface delete: %p at %s:%d",
92  static_cast<void*>(surface), file, line);
93  }
94  else
95  {
96  SDLMemoryObject *const obj = (*it).second;
97  if (obj)
98  {
99  const int cnt = obj->mCnt;
100 #ifdef DEBUG_SURFACE_ALLOCATION
101  logger->log("debug deleting surface: %p, count:%d\n"
102  "was add %s\nwas deleted %s", surface, cnt,
103  obj->mAddFile.c_str(), obj->mRemoveFile.c_str());
104 #endif // DEBUG_SURFACE_ALLOCATION
105 
106  if (cnt < 1)
107  { // surface was here but was deleted
108  logger->log("deleting already deleted surface: %p at %s:%d\n"
109  "was add %s\nwas deleted %s", static_cast<void*>(surface),
110  file, line, obj->mAddFile.c_str(),
111  obj->mRemoveFile.c_str());
112  }
113  else if (cnt == 1)
114  {
115  mSurfaces.erase(surface);
116  delete obj;
117  }
118  else
119  {
120  obj->mCnt --;
121  obj->mRemoveFile = strprintf("%s:%u", file, line);
122  }
123  }
124  }
125 }
126 
127 SDL_Surface *FakeIMG_LoadPNG_RW(SDL_RWops *const src, const char *const file,
128  const unsigned line)
129 {
130  return addSurface("IMG_LoadPNG_RW", IMG_LoadPNG_RW(src), file, line);
131 }
132 
133 SDL_Surface *FakeIMG_LoadJPG_RW(SDL_RWops *const src, const char *const file,
134  const unsigned line)
135 {
136  return addSurface("IMG_LoadJPG_RW", IMG_LoadJPG_RW(src), file, line);
137 }
138 
139 SDL_Surface *FakeIMG_Load(const char *name, const char *const file,
140  const unsigned line)
141 {
142  return addSurface("IMG_Load", IMG_Load(name), file, line);
143 }
144 
145 void FakeSDL_FreeSurface(SDL_Surface *const surface, const char *const file,
146  const unsigned line)
147 {
148  deleteSurface("SDL_FreeSurface", surface, file, line);
149  SDL_FreeSurface(surface);
150 }
151 
152 SDL_Surface *FakeSDL_CreateRGBSurface(const uint32_t flags,
153  const int width, const int height,
154  const int depth,
155  const uint32_t rMask,
156  const uint32_t gMask,
157  const uint32_t bMask,
158  const uint32_t aMask,
159  const char *const file,
160  const unsigned line)
161 {
162  return addSurface("SDL_CreateRGBSurface", SDL_CreateRGBSurface(flags,
163  width, height, depth, rMask, gMask, bMask, aMask), file, line);
164 }
165 
166 SDL_Surface *FakeSDL_ConvertSurface(SDL_Surface *const src,
167  SDL_PixelFormat *const fmt,
168  const uint32_t flags,
169  const char *const file,
170  const unsigned line)
171 {
172  return addSurface("SDL_ConvertSurface", SDL_ConvertSurface(
173  src, fmt, flags), file, line);
174 }
175 
176 SDL_Surface *FakeTTF_RenderUTF8_Blended(_TTF_Font *const font,
177  const char *restrict const text,
178  const SDL_Color &fg,
179  const char *restrict const file,
180  const unsigned line)
181 {
182  return addSurface("TTF_RenderUTF8_Blended", TTF_RenderUTF8_Blended(
183  font, text, fg), file, line);
184 }
185 
186 SDL_Surface *FakeSDL_DisplayFormat(SDL_Surface *const surface,
187  const char *const file,
188  const unsigned line)
189 {
190  return addSurface("SDL_DisplayFormat",
191  SDL_DisplayFormat(surface), file, line);
192 }
193 
194 SDL_Surface *FakeSDL_DisplayFormatAlpha(SDL_Surface *const surface,
195  const char *const file,
196  const unsigned line)
197 {
198  return addSurface("SDL_DisplayFormatAlpha",
199  SDL_DisplayFormatAlpha(surface), file, line);
200 }
201 
202 #endif // DEBUG_SDL_SURFACES
void log(const char *const log_text,...)
Definition: logger.cpp:269
#define restrict
Definition: localconsts.h:165
#define PRAGMA48(str)
Definition: localconsts.h:199
#define A_UNUSED
Definition: localconsts.h:160
Logger * logger
Definition: logger.cpp:89
std::string strprintf(const char *const format,...)