Coverage Report

Created: 2026-02-14 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/src/OgreRenderSystemCapabilitiesSerializer.cpp
Line
Count
Source
1
/*
2
-----------------------------------------------------------------------------
3
This source file is part of OGRE
4
(Object-oriented Graphics Rendering Engine)
5
For the latest info, see http://www.ogre3d.org
6
7
Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
THE SOFTWARE.
26
-----------------------------------------------------------------------------
27
*/
28
#include "OgreStableHeaders.h"
29
30
#include "OgreRenderSystemCapabilitiesSerializer.h"
31
#include "OgreRenderSystemCapabilitiesManager.h"
32
#include "OgreRenderSystemCapabilities.h"
33
34
namespace Ogre
35
{
36
37
1
    RenderSystemCapabilitiesSerializer::RenderSystemCapabilitiesSerializer() : mCurrentLineNumber(0), mCurrentLine(0),
38
1
        mCurrentCapabilities(0)
39
1
    {
40
1
        initialiaseDispatchTables();
41
1
    }
42
    
43
    //-----------------------------------------------------------------------
44
    void RenderSystemCapabilitiesSerializer::write(const RenderSystemCapabilities* caps, const String &name, std::ostream &file)
45
0
    {
46
0
        using namespace std;
47
48
0
        file << "render_system_capabilities \"" << name << "\"" << endl;
49
0
        file << "{" << endl;
50
51
0
        file << "\t" << "render_system_name " << caps->getRenderSystemName() << endl;
52
0
        file << endl;
53
        
54
55
0
        file << "\t" << "device_name " << caps->getDeviceName() << endl;
56
0
        const DriverVersion& driverVer = caps->getDriverVersion();
57
0
        file << "\t" << "driver_version " << driverVer.toString() << endl;
58
0
        file << "\t" << "vendor " << caps->vendorToString(caps->getVendor());
59
60
0
        file << endl;
61
62
0
        file << endl;
63
64
0
        for(auto & it : mCapabilitiesMap) {
65
0
            file << "\t" << it.first << " " << StringConverter::toString(caps->hasCapability(it.second)) << endl;
66
0
        }
67
68
0
        file << endl;
69
70
0
        RenderSystemCapabilities::ShaderProfiles profiles = caps->getSupportedShaderProfiles();
71
        // write every profile
72
0
        for(const auto & profile : profiles)
73
0
        {
74
0
            file << "\t" << "shader_profile " << profile << endl;
75
0
        }
76
77
0
        file << endl;
78
0
        file << "\t" << "max_point_size " << StringConverter::toString(caps->getMaxPointSize()) << endl;
79
80
0
        file << endl;
81
0
        file << "\t" << "non_pow2_textures_limited " << StringConverter::toString(caps->getNonPOW2TexturesLimited()) << endl;
82
        
83
0
        file << endl;
84
0
        file << "\t" << "num_texture_units " << StringConverter::toString(caps->getNumTextureUnits()) << endl;
85
0
        file << "\t" << "num_multi_render_targets " << StringConverter::toString(caps->getNumMultiRenderTargets()) << endl;
86
0
        file << "\t" << "vertex_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_VERTEX_PROGRAM)) << endl;
87
0
        file << "\t" << "fragment_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_FRAGMENT_PROGRAM)) << endl;
88
0
        file << "\t" << "geometry_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_GEOMETRY_PROGRAM)) << endl;
89
0
        file << "\t" << "tessellation_hull_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_HULL_PROGRAM)) << endl;
90
0
        file << "\t" << "tessellation_domain_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_DOMAIN_PROGRAM)) << endl;
91
0
        file << "\t" << "compute_program_constant_float_count " << StringConverter::toString(caps->getConstantFloatCount(GPT_COMPUTE_PROGRAM)) << endl;
92
0
        file << "\t" << "num_vertex_texture_units " << StringConverter::toString(caps->getNumVertexTextureUnits()) << endl;
93
0
        file << "\t" << "num_vertex_attributes " << StringConverter::toString(caps->getNumVertexAttributes()) << endl;
94
95
0
        file << endl;
96
97
0
        file << "}" << endl;
98
0
    }
99
100
    //-----------------------------------------------------------------------
101
    void RenderSystemCapabilitiesSerializer::writeScript(const RenderSystemCapabilities* caps, const String &name, const String& filename)
102
0
    {
103
0
        using namespace std;
104
105
0
        ofstream file(filename.c_str());
106
107
0
        write(caps, name, file);
108
109
0
        file.close();
110
0
    }
111
    
112
    //-----------------------------------------------------------------------
113
    String RenderSystemCapabilitiesSerializer::writeString(const RenderSystemCapabilities* caps, const String &name)
114
0
    {
115
0
        using namespace std;
116
        
117
0
        stringstream stream;
118
        
119
0
        write(caps, name, stream);
120
        
121
0
        return stream.str();
122
0
    }
123
124
    //-----------------------------------------------------------------------
125
    void RenderSystemCapabilitiesSerializer::parseScript(DataStreamPtr& stream)
126
0
    {
127
        // reset parsing data to NULL
128
0
        mCurrentLineNumber = 0;
129
0
        mCurrentLine = 0;
130
0
        mCurrentStream.reset();
131
0
        mCurrentCapabilities = 0;
132
133
0
        mCurrentStream = stream;
134
135
        // parser operating data
136
0
        String line;
137
0
        ParseAction parseAction = PARSE_HEADER;
138
0
        StringVector tokens;
139
0
        bool parsedAtLeastOneRSC = false;
140
141
        // collect capabilities lines (i.e. everything that is not header, "{", "}",
142
        // comment or empty line) for further processing
143
0
        CapabilitiesLinesList capabilitiesLines;
144
145
        // for reading data
146
0
        char tmpBuf[OGRE_STREAM_TEMP_SIZE]; 
147
148
149
        // TODO: build a smarter tokenizer so that "{" and "}"
150
        // don't need separate lines
151
0
        while (!stream->eof())
152
0
        {
153
0
            stream->readLine(tmpBuf, OGRE_STREAM_TEMP_SIZE-1);
154
0
            line = String(tmpBuf);
155
0
            StringUtil::trim(line);
156
157
            // keep track of parse position
158
0
            mCurrentLine = &line;
159
0
            mCurrentLineNumber++;
160
161
0
            tokens = StringUtil::split(line);
162
163
            // skip empty and comment lines
164
            // TODO: handle end of line comments
165
0
            if (tokens[0] == "" || tokens[0].substr(0,2) == "//")
166
0
                continue;
167
168
0
            switch (parseAction)
169
0
            {
170
                // header line must look like this:
171
                // render_system_capabilities "Vendor Card Name Version xx.xxx"
172
173
0
                case PARSE_HEADER:
174
175
0
                    if(tokens[0] != "render_system_capabilities")
176
0
                    {
177
0
                        logParseError("The first keyword must be render_system_capabilities. RenderSystemCapabilities NOT created!");
178
0
                        return;
179
0
                    }
180
0
                    else
181
0
                    {
182
                        // the rest of the tokens are irrevelant, beause everything between "..." is one name
183
0
                        String rscName = line.substr(tokens[0].size());
184
0
                        StringUtil::trim(rscName);
185
186
                        // the second argument must be a "" delimited string
187
0
                        if (!StringUtil::match(rscName, "\"*\""))
188
0
                        {
189
0
                            logParseError("The argument to render_system_capabilities must be a quote delimited (\"...\") string. RenderSystemCapabilities NOT created!");
190
0
                            return;
191
0
                        }
192
0
                        else
193
0
                        {
194
                            // we have a valid header
195
196
                            // remove quotes
197
0
                            rscName = rscName.substr(1);
198
0
                            rscName = rscName.substr(0, rscName.size() - 1);
199
200
                            // create RSC
201
0
                            mCurrentCapabilities = OGRE_NEW RenderSystemCapabilities();
202
                            // RSCManager is responsible for deleting mCurrentCapabilities
203
0
                            RenderSystemCapabilitiesManager::getSingleton()._addRenderSystemCapabilities(rscName, mCurrentCapabilities);
204
205
0
                            LogManager::getSingleton().logMessage("Created RenderSystemCapabilities" + rscName);
206
207
                            // do next action
208
0
                            parseAction = FIND_OPEN_BRACE;
209
0
                            parsedAtLeastOneRSC = true;
210
0
                        }
211
0
                    }
212
213
0
                break;
214
215
0
                case FIND_OPEN_BRACE:
216
0
                    if (tokens[0] != "{" || tokens.size() != 1)
217
0
                    {
218
0
                        logParseError("Expected '{' got: " + line + ". Continuing to next line.");
219
0
                    }
220
0
                    else
221
0
                    {
222
0
                        parseAction = COLLECT_LINES;
223
0
                    }
224
225
0
                break;
226
227
0
                case COLLECT_LINES:
228
0
                    if (tokens[0] == "}")
229
0
                    {
230
                        // this render_system_capabilities section is over
231
                        // let's process the data and look for the next one
232
0
                        parseCapabilitiesLines(capabilitiesLines);
233
0
                        capabilitiesLines.clear();
234
0
                        parseAction = PARSE_HEADER;
235
236
0
                    }
237
0
                    else
238
0
                        capabilitiesLines.push_back(CapabilitiesLinesList::value_type(line, mCurrentLineNumber));
239
0
                break;
240
241
0
            }
242
0
        }
243
244
        // Datastream is empty
245
        // if we are still looking for header, this means that we have either
246
        // finished reading one, or this is an empty file
247
0
        if(parseAction == PARSE_HEADER && parsedAtLeastOneRSC == false)
248
0
        {
249
0
            logParseError ("The file is empty");
250
0
        }
251
0
        if(parseAction == FIND_OPEN_BRACE)
252
253
0
        {
254
0
            logParseError ("Bad .rendercaps file. Were not able to find a '{'");
255
0
        }
256
0
        if(parseAction == COLLECT_LINES)
257
0
        {
258
0
            logParseError ("Bad .rendercaps file. Were not able to find a '}'");
259
0
        }
260
261
0
    }
262
263
    void RenderSystemCapabilitiesSerializer::initialiaseDispatchTables()
264
1
    {
265
        // set up driver version parsing
266
1
        addKeywordType("driver_version", SET_STRING_METHOD);
267
        // set up the setters for driver versions
268
1
        addSetStringMethod("driver_version", &RenderSystemCapabilities::parseDriverVersionFromString);
269
        
270
        // set up device name parsing
271
1
        addKeywordType("device_name", SET_STRING_METHOD);
272
        // set up the setters for device names
273
1
        addSetStringMethod("device_name", &RenderSystemCapabilities::setDeviceName);
274
        
275
        // set up render system name parsing
276
1
        addKeywordType("render_system_name", SET_STRING_METHOD);
277
        // set up the setters 
278
1
        addSetStringMethod("render_system_name", &RenderSystemCapabilities::setRenderSystemName);
279
280
        // set up vendor parsing
281
1
        addKeywordType("vendor", SET_STRING_METHOD);
282
        // set up the setters for driver versions
283
1
        addSetStringMethod("vendor", &RenderSystemCapabilities::parseVendorFromString);
284
285
        // initialize int types
286
1
        addKeywordType("num_world_matrices", SET_INT_METHOD);
287
1
        addKeywordType("num_texture_units", SET_INT_METHOD);
288
1
        addKeywordType("stencil_buffer_bit_depth", SET_INT_METHOD);
289
1
        addKeywordType("num_vertex_blend_matrices", SET_INT_METHOD);
290
1
        addKeywordType("num_multi_render_targets", SET_INT_METHOD);
291
1
        addKeywordType("vertex_program_constant_float_count", SET_INT_METHOD);
292
1
        addKeywordType("vertex_program_constant_int_count", SET_INT_METHOD);
293
1
        addKeywordType("vertex_program_constant_bool_count", SET_INT_METHOD);
294
1
        addKeywordType("fragment_program_constant_float_count", SET_INT_METHOD);
295
1
        addKeywordType("fragment_program_constant_int_count", SET_INT_METHOD);
296
1
        addKeywordType("fragment_program_constant_bool_count", SET_INT_METHOD);
297
1
        addKeywordType("geometry_program_constant_float_count", SET_INT_METHOD);
298
1
        addKeywordType("geometry_program_constant_int_count", SET_INT_METHOD);
299
1
        addKeywordType("geometry_program_constant_bool_count", SET_INT_METHOD);
300
1
        addKeywordType("tessellation_hull_program_constant_float_count", SET_INT_METHOD);
301
1
        addKeywordType("tessellation_hull_program_constant_int_count", SET_INT_METHOD);
302
1
        addKeywordType("tessellation_hull_program_constant_bool_count", SET_INT_METHOD);
303
1
        addKeywordType("tessellation_domain_program_constant_float_count", SET_INT_METHOD);
304
1
        addKeywordType("tessellation_domain_program_constant_int_count", SET_INT_METHOD);
305
1
        addKeywordType("tessellation_domain_program_constant_bool_count", SET_INT_METHOD);
306
1
        addKeywordType("compute_program_constant_float_count", SET_INT_METHOD);
307
1
        addKeywordType("compute_program_constant_int_count", SET_INT_METHOD);
308
1
        addKeywordType("compute_program_constant_bool_count", SET_INT_METHOD);
309
1
        addKeywordType("num_vertex_texture_units", SET_INT_METHOD);
310
311
        // initialize int setters
312
1
        addSetIntMethod("num_texture_units", &RenderSystemCapabilities::setNumTextureUnits);
313
1
        addSetIntMethod("stencil_buffer_bit_depth", &RenderSystemCapabilities::setStencilBufferBitDepth);
314
1
        addSetIntMethod("num_multi_render_targets", &RenderSystemCapabilities::setNumMultiRenderTargets);
315
1
        addSetIntMethod("vertex_program_constant_float_count", &RenderSystemCapabilities::setVertexProgramConstantFloatCount);
316
1
        addSetIntMethod("fragment_program_constant_float_count", &RenderSystemCapabilities::setFragmentProgramConstantFloatCount);
317
1
        addSetIntMethod("geometry_program_constant_float_count", &RenderSystemCapabilities::setGeometryProgramConstantFloatCount);
318
1
        addSetIntMethod("tessellation_hull_program_constant_float_count", &RenderSystemCapabilities::setTessellationHullProgramConstantFloatCount);
319
1
        addSetIntMethod("tessellation_domain_program_constant_float_count", &RenderSystemCapabilities::setTessellationDomainProgramConstantFloatCount);
320
1
        addSetIntMethod("compute_program_constant_float_count", &RenderSystemCapabilities::setComputeProgramConstantFloatCount);
321
1
        addSetIntMethod("num_vertex_texture_units", &RenderSystemCapabilities::setNumVertexTextureUnits);
322
323
        // initialize bool types
324
1
        addKeywordType("non_pow2_textures_limited", SET_BOOL_METHOD);
325
326
        // initialize bool setters
327
1
        addSetBoolMethod("non_pow2_textures_limited", &RenderSystemCapabilities::setNonPOW2TexturesLimited);
328
329
        // initialize Real types
330
1
        addKeywordType("max_point_size", SET_REAL_METHOD);
331
332
        // initialize Real setters
333
1
        addSetRealMethod("max_point_size", &RenderSystemCapabilities::setMaxPointSize);
334
335
        // there is no dispatch table for shader profiles, just the type
336
1
        addKeywordType("shader_profile", ADD_SHADER_PROFILE_STRING);
337
338
1
        addCapabilitiesMapping("fixed_function", RSC_FIXED_FUNCTION);
339
1
        addCapabilitiesMapping("anisotropy", RSC_ANISOTROPY);
340
1
        addCapabilitiesMapping("hwstencil", RSC_HWSTENCIL);
341
1
        addCapabilitiesMapping("32bit_index", RSC_32BIT_INDEX);
342
1
        addCapabilitiesMapping("vertex_program", RSC_VERTEX_PROGRAM);
343
1
        addCapabilitiesMapping("geometry_program", RSC_GEOMETRY_PROGRAM);
344
1
        addCapabilitiesMapping("tessellation_hull_program", RSC_TESSELLATION_HULL_PROGRAM);
345
1
        addCapabilitiesMapping("tessellation_domain_program", RSC_TESSELLATION_DOMAIN_PROGRAM);
346
1
        addCapabilitiesMapping("compute_program", RSC_COMPUTE_PROGRAM);
347
1
        addCapabilitiesMapping("two_sided_stencil", RSC_TWO_SIDED_STENCIL);
348
1
        addCapabilitiesMapping("stencil_wrap", RSC_STENCIL_WRAP);
349
1
        addCapabilitiesMapping("hwocclusion", RSC_HWOCCLUSION);
350
1
        addCapabilitiesMapping("user_clip_planes", RSC_USER_CLIP_PLANES);
351
1
        addCapabilitiesMapping("hwrender_to_texture", RSC_HWRENDER_TO_TEXTURE);
352
1
        addCapabilitiesMapping("texture_float", RSC_TEXTURE_FLOAT);
353
1
        addCapabilitiesMapping("non_power_of_2_textures", RSC_NON_POWER_OF_2_TEXTURES);
354
1
        addCapabilitiesMapping("texture_3d", RSC_TEXTURE_3D);
355
1
        addCapabilitiesMapping("texture_2d_array", RSC_TEXTURE_3D);
356
1
        addCapabilitiesMapping("texture_1d", RSC_TEXTURE_1D);
357
1
        addCapabilitiesMapping("point_sprites", RSC_POINT_SPRITES);
358
1
        addCapabilitiesMapping("wide_lines", RSC_WIDE_LINES);
359
1
        addCapabilitiesMapping("vertex_texture_fetch", RSC_VERTEX_TEXTURE_FETCH);
360
1
        addCapabilitiesMapping("mipmap_lod_bias", RSC_MIPMAP_LOD_BIAS);
361
1
        addCapabilitiesMapping("atomic_counters", RSC_READ_WRITE_BUFFERS);
362
1
        addCapabilitiesMapping("texture_compression", RSC_TEXTURE_COMPRESSION);
363
1
        addCapabilitiesMapping("texture_compression_dxt", RSC_TEXTURE_COMPRESSION_DXT);
364
1
        addCapabilitiesMapping("texture_compression_vtc", RSC_TEXTURE_COMPRESSION_VTC);
365
1
        addCapabilitiesMapping("texture_compression_pvrtc", RSC_TEXTURE_COMPRESSION_PVRTC);
366
1
        addCapabilitiesMapping("texture_compression_atc", RSC_TEXTURE_COMPRESSION_ATC);
367
1
        addCapabilitiesMapping("texture_compression_etc1", RSC_TEXTURE_COMPRESSION_ETC1);
368
1
        addCapabilitiesMapping("texture_compression_etc2", RSC_TEXTURE_COMPRESSION_ETC2);
369
1
        addCapabilitiesMapping("texture_compression_bc4_bc5", RSC_TEXTURE_COMPRESSION_BC4_BC5);
370
1
        addCapabilitiesMapping("texture_compression_bc6h_bc7", RSC_TEXTURE_COMPRESSION_BC6H_BC7);
371
1
        addCapabilitiesMapping("texture_compression_astc", RSC_TEXTURE_COMPRESSION_ASTC);
372
1
        addCapabilitiesMapping("hwrender_to_vertex_buffer", RSC_HWRENDER_TO_VERTEX_BUFFER);
373
374
1
        addCapabilitiesMapping("pbuffer", RSC_PBUFFER);
375
1
        addCapabilitiesMapping("perstageconstant", RSC_PERSTAGECONSTANT);
376
1
        addCapabilitiesMapping("vao", RSC_VAO);
377
1
        addCapabilitiesMapping("separate_shader_objects", RSC_SEPARATE_SHADER_OBJECTS);
378
1
        addCapabilitiesMapping("glsl_sso_redeclare", RSC_GLSL_SSO_REDECLARE);
379
1
        addCapabilitiesMapping("debug", RSC_DEBUG);
380
1
        addCapabilitiesMapping("mapbuffer", RSC_MAPBUFFER);
381
1
        addCapabilitiesMapping("automipmap_compressed", RSC_AUTOMIPMAP_COMPRESSED);
382
1
    }
383
384
    void RenderSystemCapabilitiesSerializer::parseCapabilitiesLines(CapabilitiesLinesList& lines)
385
0
    {
386
0
        StringVector tokens;
387
388
0
        for (auto & line : lines)
389
0
        {
390
            // restore the current line information for debugging
391
0
            mCurrentLine = &(line.first);
392
0
            mCurrentLineNumber = line.second;
393
394
0
            tokens = StringUtil::split(line.first);
395
            // check for incomplete lines
396
0
            if(tokens.size() < 2)
397
0
            {
398
0
                logParseError("No parameters given for the capability keyword");
399
0
                continue;
400
0
            }
401
402
            // the first token must the the keyword identifying the capability
403
            // the remaining tokens are the parameters
404
0
            String keyword = tokens[0];
405
0
            String everythingElse = "";
406
0
            for(unsigned int i = 1; i < tokens.size() - 1; i ++)
407
0
            {
408
0
                everythingElse = everythingElse + tokens[i] + " ";
409
0
            }
410
0
            everythingElse = everythingElse + tokens[tokens.size() - 1];
411
412
0
            CapabilityKeywordType keywordType = getKeywordType(keyword);
413
414
0
            switch(keywordType)
415
0
            {
416
0
                case UNDEFINED_CAPABILITY_TYPE:
417
0
                    logParseError("Unknown capability keyword: " + keyword);
418
0
                    break;
419
0
                case SET_STRING_METHOD:
420
0
                    callSetStringMethod(keyword, everythingElse);
421
0
                    break;
422
0
                case SET_INT_METHOD:
423
0
                {
424
0
                    ushort integer = (ushort)StringConverter::parseInt(tokens[1]);
425
0
                    callSetIntMethod(keyword, integer);
426
0
                    break;
427
0
                }
428
0
                case SET_BOOL_METHOD:
429
0
                {
430
0
                    bool b = StringConverter::parseBool(tokens[1]);
431
0
                    callSetBoolMethod(keyword, b);
432
0
                    break;
433
0
                }
434
0
                case SET_REAL_METHOD:
435
0
                {
436
0
                    Real real = StringConverter::parseReal(tokens[1]);
437
0
                    callSetRealMethod(keyword, real);
438
0
                    break;
439
0
                }
440
0
                case ADD_SHADER_PROFILE_STRING:
441
0
                {
442
0
                    addShaderProfile(tokens[1]);
443
0
                    break;
444
0
                }
445
0
                case SET_CAPABILITY_ENUM_BOOL:
446
0
                {
447
0
                    bool b = StringConverter::parseBool(tokens[1]);
448
0
                    setCapabilityEnumBool(tokens[0], b);
449
0
                    break;
450
0
                }
451
0
            }
452
0
        }
453
0
    }
454
455
    void RenderSystemCapabilitiesSerializer::logParseError(const String& error) const
456
0
    {
457
        // log the line with error in it if the current line is available
458
0
        if (mCurrentLine != 0 && mCurrentStream)
459
0
        {
460
0
            LogManager::getSingleton().logMessage(
461
0
                "Error in .rendercaps " + mCurrentStream->getName() + ":" + StringConverter::toString(mCurrentLineNumber) +
462
0
                " : " + error);
463
0
        }
464
0
        else if (mCurrentStream)
465
0
        {
466
0
            LogManager::getSingleton().logMessage(
467
0
                "Error in .rendercaps " + mCurrentStream->getName() +
468
0
                " : " + error);
469
0
        }
470
0
    }
471
472
}
473
474