|
Steam Client interference / OpenGL |
thebignic
Member #14,419
July 2012
|
Allegro 5.2.5.1 I've been recommending to players to disable the Steam Overlay as it seems to be the source of an intermittent exception (specifically with al_load_bitmap()) with some OpenGL drivers (usually laptops, shared memory?) but recently the Steam Client seems to interfere with my game even if the overlay is disabled for the game in specific, AND in the Steam Client global settings! Bashing my head off the desk... Game loads and runs fine if the Steam Client just isn't running, but since we're trying to use Steam for multiplayer, we need the client to run. Has anyone experienced anything similar?
|
Chris Katko
Member #1,881
January 2002
|
Hello bignic, love your music. Do you have the type of exception? Have you been able to replicate it on any of your home machines or a VM, or only from users? Or do you have reported/saved the exception data / call-stack from users? Does the exception only fire off in certain, specific al_load_bitmaps calls, or any of them? I've definitely seen crashes when the Steam overlay activates. In one scenario, one screenshot, it'll crash--especially if it's a large screen (4K) into a slow hard drive. But not specifically with Allegro. Steam docs said:
Q. Why is the Steam overlay crashing my app? That's interesting. -----sig: |
thebignic
Member #14,419
July 2012
|
I can replicate it fairly often with an HP EliteBook with Intel HD 3000 onboard gpu. It usually crashes in 1-3 exact same spots so I'm not ruling out a memory leak in my own code. Null reference - when I got PDB loaded, al_really_load_png() throws "lock was nullptr" (I probably shouldn't have started two threads here, but the other thread was specifically about loading the PDBs which seems to be fine now, just not that helpful after all.)
|
Chris Katko
Member #1,881
January 2002
|
1
2/* really_load_png:
3 * Worker routine, used by load_png and load_memory_png.
4 */
5static ALLEGRO_BITMAP *really_load_png(png_structp png_ptr, png_infop info_ptr,
6 int flags)
7{
8 ALLEGRO_BITMAP *bmp;
9 png_uint_32 width, height, rowbytes, real_rowbytes;
10 int bit_depth, color_type, interlace_type;
11 double image_gamma, screen_gamma;
12 int intent;
13 int bpp;
14 int number_passes, pass;
15 int num_trans = 0;
16 PalEntry pal[256];
17 png_bytep trans;
18 ALLEGRO_LOCKED_REGION *lock;
19 unsigned char *buf;
20 unsigned char *dest;
21 bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA);
22 bool index_only;
23
24 ALLEGRO_ASSERT(png_ptr && info_ptr);
25
26 /* The call to png_read_info() gives us all of the information from the
27 * PNG file before the first IDAT (image data chunk).
28 */
29 png_read_info(png_ptr, info_ptr);
30
31 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
32 &color_type, &interlace_type, NULL, NULL);
33
34 /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
35 * byte into separate bytes (useful for paletted and grayscale images).
36 */
37 png_set_packing(png_ptr);
38
39 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
40 if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8))
41 png_set_expand(png_ptr);
42
43 /* Adds a full alpha channel if there is transparency information
44 * in a tRNS chunk.
45 */
46 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
47 if (!(color_type & PNG_COLOR_MASK_PALETTE))
48 png_set_tRNS_to_alpha(png_ptr);
49 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
50 }
51
52 /* Convert 16-bits per colour component to 8-bits per colour component. */
53 if (bit_depth == 16)
54 png_set_strip_16(png_ptr);
55
56 /* Convert grayscale to RGB triplets */
57 if ((color_type == PNG_COLOR_TYPE_GRAY) ||
58 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
59 png_set_gray_to_rgb(png_ptr);
60
61 /* Optionally, tell libpng to handle the gamma correction for us. */
62 screen_gamma = get_gamma();
63 if (screen_gamma != 0.0) {
64 if (png_get_sRGB(png_ptr, info_ptr, &intent))
65 png_set_gamma(png_ptr, screen_gamma, 0.45455);
66 else {
67 if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
68 png_set_gamma(png_ptr, screen_gamma, image_gamma);
69 else
70 png_set_gamma(png_ptr, screen_gamma, 0.45455);
71 }
72 }
73
74 /* Turn on interlace handling. */
75 number_passes = png_set_interlace_handling(png_ptr);
76
77 /* Call to gamma correct and add the background to the palette
78 * and update info structure.
79 */
80 png_read_update_info(png_ptr, info_ptr);
81
82 /* Palettes. */
83 if (color_type & PNG_COLOR_MASK_PALETTE) {
84 int num_palette, i;
85 png_colorp palette;
86
87 if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) {
88 /* We don't actually dither, we just copy the palette. */
89 for (i = 0; ((i < num_palette) && (i < 256)); i++) {
90 pal[i].r = palette[i].red;
91 pal[i].g = palette[i].green;
92 pal[i].b = palette[i].blue;
93 }
94
95 for (; i < 256; i++)
96 pal[i].r = pal[i].g = pal[i].b = 0;
97 }
98 }
99
100 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
101
102 /* Allocate the memory to hold the image using the fields of info_ptr. */
103 bpp = rowbytes * 8 / width;
104
105 /* Allegro cannot handle less than 8 bpp. */
106 if (bpp < 8)
107 bpp = 8;
108
109
110 if ((bpp == 24) || (bpp == 32)) {
111#ifdef ALLEGRO_BIG_ENDIAN
112 png_set_bgr(png_ptr);
113 png_set_swap_alpha(png_ptr);
114#endif
115 }
116
117 bmp = al_create_bitmap(width, height);
118 if (!bmp) {
119 ALLEGRO_ERROR("al_create_bitmap failed while loading PNG.\n");
120 return NULL;
121 }
122
123 // TODO: can this be different from rowbytes?
124 real_rowbytes = ((bpp + 7) / 8) * width;
125 if (interlace_type == PNG_INTERLACE_ADAM7)
126 buf = al_malloc(real_rowbytes * height);
127 else
128 buf = al_malloc(real_rowbytes);
129
130 if (bpp == 8 && (color_type & PNG_COLOR_MASK_PALETTE) &&
131 (flags & ALLEGRO_KEEP_INDEX))
132 {
133 lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8,
134 ALLEGRO_LOCK_WRITEONLY);
135 index_only = true;
136 }
137 else {
138 lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE,
139 ALLEGRO_LOCK_WRITEONLY);
140 index_only = false;
141 }
142
143 /* Read the image, one line at a time (easier to debug!) */
144 for (pass = 0; pass < number_passes; pass++) {
145 png_uint_32 y;
146 unsigned int i;
147 unsigned char *ptr;
148 dest = lock->data;
149
150 for (y = 0; y < height; y++) {
151 unsigned char *dest_row_start = dest;
152 /* For interlaced pictures, the row needs to be initialized with
153 * the contents of the previous pass.
154 */
155 if (interlace_type == PNG_INTERLACE_ADAM7)
156 ptr = buf + y * real_rowbytes;
157 else
158 ptr = buf;
159 png_read_row(png_ptr, NULL, ptr);
160
161 switch (bpp) {
162 case 8:
163 if (index_only) {
164 for (i = 0; i < width; i++) {
165 *(dest++) = *(ptr++);
166 }
167 }
168 else if (color_type & PNG_COLOR_MASK_PALETTE) {
169 for (i = 0; i < width; i++) {
170 int pix = ptr[0];
171 ptr++;
172 dest[0] = pal[pix].r;
173 dest[1] = pal[pix].g;
174 dest[2] = pal[pix].b;
175 if (pix < num_trans) {
176 int a = trans[pix];
177 dest[3] = a;
178 if (premul) {
179 dest[0] = dest[0] * a / 255;
180 dest[1] = dest[1] * a / 255;
181 dest[2] = dest[2] * a / 255;
182 }
183 } else {
184 dest[3] = 255;
185 }
186 dest += 4;
187 }
188 }
189 else {
190 for (i = 0; i < width; i++) {
191 int pix = ptr[0];
192 ptr++;
193 *(dest++) = pix;
194 *(dest++) = pix;
195 *(dest++) = pix;
196 *(dest++) = 255;
197 }
198 }
199 break;
200
201 case 24:
202 for (i = 0; i < width; i++) {
203 uint32_t pix = _AL_READ3BYTES(ptr);
204 ptr += 3;
205 *(dest++) = pix & 0xff;
206 *(dest++) = (pix >> 8) & 0xff;
207 *(dest++) = (pix >> 16) & 0xff;
208 *(dest++) = 255;
209 }
210 break;
211
212 case 32:
213 for (i = 0; i < width; i++) {
214 uint32_t pix = *(uint32_t*)ptr;
215 int r = pix & 0xff;
216 int g = (pix >> 8) & 0xff;
217 int b = (pix >> 16) & 0xff;
218 int a = (pix >> 24) & 0xff;
219 ptr += 4;
220
221 if (premul) {
222 r = r * a / 255;
223 g = g * a / 255;
224 b = b * a / 255;
225 }
226
227 *(dest++) = r;
228 *(dest++) = g;
229 *(dest++) = b;
230 *(dest++) = a;
231 }
232 break;
233
234 default:
235 ALLEGRO_ASSERT(bpp == 8 || bpp == 24 || bpp == 32);
236 break;
237 }
238 dest = dest_row_start + lock->pitch;
239 }
240 }
241
242 al_unlock_bitmap(bmp);
243
244 al_free(buf);
245
246 /* Read rest of file, and get additional chunks in info_ptr. */
247 png_read_end(png_ptr, info_ptr);
248
249 return bmp;
250}
- I wonder if steam overlay does some kind of weird file locking / freezes threads as it loads the overlay. Also, bignic, I've not used it but the Valgrind people recommend "Deleaker" for Windows equivalent of finding memory leaks. It might be helpful. The fact you can semi-consistently trigger it will definitely help. I wonder if this can be triggered on any of the included Allegro 5 example programs by forcing Steam to attach the overlay to it. (IIRC, you can start anything with steam overlay attached if you add the shortcut to Steam manually under Steam->Games->"Add Non-Steam Game to my Library".) Also, there are ALLEGRO_ERROR lines in here. So if compiled in debug mode (also release?) Allegro should dump to an error file if it catches it. I'd do more searching but apparently Github decided I'm a Russian bot. Great job github. Apparently scrolling through pages of hits for "ALLEGRO_ERROR" means you're a bot. (And no, I'm not on a VPN either.) {"name":"B1NDVaI.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/7\/072821ef61fdf27881457f8e42193f91.png","w":454,"h":334,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/7\/072821ef61fdf27881457f8e42193f91"} -----sig: |
thebignic
Member #14,419
July 2012
|
Thank you kindly for the suggestions - Some new paths to investigate, for sure. I'll have to work up some courage to press on!
|
|