Stability Fixes, adapted to new Interfaces, Rendering concept rewritten
[profile/ivi/layer-management.git] / LayerManagerPlugins / Renderers / Base / include / RenderUtil.h
1 /***************************************************************************
2 *
3 * Copyright 2010,2011 BMW Car IT GmbH
4 *
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *               http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19
20 #ifndef _RENDERUTIL_H_
21 #define _RENDERUTIL_H_
22
23 #include "GLES2/gl2.h"
24 #include "Log.h"
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <iostream>
29
30 // Loads a file containing shader code
31 static char* RenderUtilLoadShaderFile(const char *szFilename)
32 {
33     if(!szFilename)
34     {
35         return(NULL);
36     }
37
38     FILE *pFile;
39     pFile = fopen(szFilename, "rb");
40     if(!pFile)
41     {
42         LOG_ERROR("RenderUtilLoadShaderFile","Unable to open ShaderFile " << szFilename);
43         return(NULL);
44     }
45
46     fseek(pFile, 0, SEEK_END);
47     long size = ftell(pFile);
48     fseek(pFile, 0, SEEK_SET);
49
50     char *pBuffer = new char[size+1];
51     if(!pBuffer)
52     {
53         LOG_ERROR("RenderUtilLoadShaderFile","Unable to allocate Memory for ShaderFile " << szFilename);
54         fclose(pFile);
55         return(NULL);
56     }
57
58     if(1 != fread(pBuffer, size, 1, pFile))
59     {
60         LOG_ERROR("RenderUtilLoadShaderFile","Unable to allocate Memory for ShaderFile " << szFilename);
61         fclose(pFile);
62         delete [] pBuffer;
63         return(NULL);
64     }
65
66     pBuffer[size] = 0;
67     fclose(pFile);
68     LOG_DEBUG("RenderUtilShaderDebug","loaded file with bytes: " << size);
69     return(pBuffer);
70 }
71
72
73
74 // If shader compilation fails, prints the associated logs
75 static void RenderUtilShaderDebug(GLuint obj, GLenum status, const char* op)
76 {
77     char errorMessage[1024];
78     int success;
79     // log output.
80     int len;
81     char *str = NULL;
82     if (status == GL_COMPILE_STATUS) {
83         glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len);
84         if (len > 0) {
85                 str = new char[len];
86             glGetShaderInfoLog(obj, len, NULL, str);
87         }
88     } else { // LINK
89         glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len);
90         if (len > 0) {
91             str = new char[len];
92             glGetProgramInfoLog(obj, len, NULL, str);
93         }
94     }
95     if (str != NULL && *str != '\0') {
96         strncpy(errorMessage, "--- ",1024);
97         strncat(errorMessage,op, 1000);
98         strncat(errorMessage, " log ---", 8);
99         LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
100         LOG_DEBUG("RenderUtilShaderDebug",str);
101     }
102     if (str) { delete[] str; }
103
104     // check the compile / link status.
105     if (status == GL_COMPILE_STATUS) {
106         glGetShaderiv(obj, status, &success);
107         if (!success) {
108             glGetShaderiv(obj, GL_SHADER_SOURCE_LENGTH, &len);
109             if (len > 0) {
110                 str = new char[len];
111                 glGetShaderSource(obj, len, NULL, str);
112                 if (str != NULL && *str != '\0') {
113                         strncpy(errorMessage, "--- ",1024);
114                         strncat(errorMessage,op, 1000);
115                         strncat(errorMessage, " log ---", 8);
116                     LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
117                     LOG_DEBUG("RenderUtilShaderDebug",str);
118                 }
119                 delete[] str;
120             }
121         }
122     } else { // LINK
123         glGetProgramiv(obj, status, &success);
124     }
125
126     if (!success)
127     {
128         strncpy(errorMessage, "--- ",1024);
129         strncat(errorMessage,op, 1000);
130         strncat(errorMessage, " failed ---", 7);
131         LOG_DEBUG("RenderUtilShaderDebug",errorMessage);
132     }
133 }
134
135 // Take precompiled shader binaries and builds a shader program
136 static GLuint RenderUtilLoadShaderBinaries(
137     const char* vertBin, GLuint vertBinSize,
138     const char* fragBin, GLuint fragBinSize,
139     GLuint binaryFormat,
140     GLboolean debugging)
141 {
142 // Binary shaders not supportable for non-ES OpenGL
143 #ifdef GL_ES_VERSION_2_0
144
145     GLuint prog;
146     GLuint vertShader;
147     GLuint fragShader;
148
149     // Create the program
150     prog = glCreateProgram();
151
152     // Create the GL shader objects
153     vertShader = glCreateShader(GL_VERTEX_SHADER);
154     fragShader = glCreateShader(GL_FRAGMENT_SHADER);
155
156     // Load the binary data into the shader objects
157     glShaderBinary(1, &vertShader,
158                                         binaryFormat, vertBin, vertBinSize);
159     glShaderBinary(1, &fragShader,
160                                         binaryFormat, fragBin, fragBinSize);
161
162     // Attach the shaders to the program
163     glAttachShader(prog, vertShader);
164     glAttachShader(prog, fragShader);
165
166 #if 0
167     // Delete the shaders
168     glDeleteShader(vertShader);
169     glDeleteShader(fragShader);
170 #endif
171
172     // Link the shader program
173     glLinkProgram(prog);
174     if (debugging)
175         RenderUtilShaderDebug(prog, GL_LINK_STATUS, "Program Link");
176
177     return prog;
178 #else  // GL_ES_VERSION_2_0
179     return 0;
180 #endif // GL_ES_VERSION_2_0
181 }
182
183 // Takes shader source files, compiles them, and builds a shader program
184 static GLuint RenderUtilLoadShaderSources(
185     const char* vertFile,
186     const char* fragFile,
187     GLboolean debugging)
188 {
189  LOG_DEBUG("RenderUtilShaderDebug","loading shaders sources");
190  LOG_DEBUG("RenderUtilShaderDebug","loading vertex shader: " << vertFile);
191  LOG_DEBUG("RenderUtilShaderDebug","loading fragment shader: " << fragFile);
192     GLuint prog = 0;
193     char*  vertSource;
194     char*  fragSource;
195     GLint  vertSourceLen;
196     GLint  fragSourceLen;
197     GLuint vertShader;
198     GLuint fragShader;
199     GLint compiled;
200     GLint linked;
201
202     // Load the shader files
203     vertSource    =RenderUtilLoadShaderFile(vertFile);
204     fragSource    = RenderUtilLoadShaderFile(fragFile);
205  LOG_DEBUG("RenderUtilShaderDebug","loaded shaders source files");
206     if (!vertSource || !fragSource) goto done;
207     vertSourceLen = (GLint)strlen(vertSource);
208     fragSourceLen = (GLint)strlen(fragSource);
209
210     // Create the program
211     prog = glCreateProgram();
212 if (prog==0)
213          LOG_DEBUG("RenderUtilShaderDebug","could not create prog, prog is 0");
214
215     // Create the GL shader objects
216     vertShader = glCreateShader(GL_VERTEX_SHADER);
217     fragShader = glCreateShader(GL_FRAGMENT_SHADER);
218
219     // Load shader sources into GL and compile
220     glShaderSource(vertShader, 1, (const char**)&vertSource, &vertSourceLen);
221     glCompileShader(vertShader);
222     if (debugging)
223         RenderUtilShaderDebug(vertShader, GL_COMPILE_STATUS, "Vert Compile");
224
225     glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compiled);
226     if (compiled)
227     {
228         glShaderSource(fragShader, 1, (const char**)&fragSource, &fragSourceLen);
229         glCompileShader(fragShader);
230         if (debugging)
231                 RenderUtilShaderDebug(fragShader, GL_COMPILE_STATUS, "Frag Compile");
232         glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compiled);
233         if (compiled)
234         {
235             // Attach the shaders to the program
236             glAttachShader(prog, vertShader);
237             glAttachShader(prog, fragShader);
238
239             // Delete the shaders
240             glDeleteShader(vertShader);
241             glDeleteShader(fragShader);
242
243             // Link and validate the shader program
244             glLinkProgram(prog);
245
246             if (debugging)
247                 RenderUtilShaderDebug(prog, GL_LINK_STATUS, "Program Link");
248             glValidateProgram(prog);
249             if (debugging)
250                 RenderUtilShaderDebug(prog, GL_VALIDATE_STATUS, "Program Validate");
251
252             glGetProgramiv(prog, GL_LINK_STATUS, &linked);
253             if (!linked)
254                  LOG_DEBUG("RenderUtilShaderDebug","could not link shader");
255         }else{
256                  LOG_DEBUG("RenderUtilShaderDebug","could not compile fragment shader");
257 }
258
259     }else{
260          LOG_DEBUG("RenderUtilShaderDebug","could not compile vertex shader");
261 }
262
263     if (!compiled || !linked)
264     {
265         glDeleteProgram(prog);
266         prog = 0;
267     }
268
269     done:
270
271     delete[] fragSource;
272     delete[] vertSource;
273     return prog;
274 }
275
276 #endif /* _RENDERUTIL_H_ */