Subversion Repositories Kolibri OS

Rev

Rev 4517 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4502 Serge 1
#include 
2
#include 
3
#include 
4
#include 
5
 
6
#include "render.h"
7
#include 
8
#include 
9
 
10
 
11
static int drm_ioctl(int fd, unsigned long request, void *arg)
12
{
13
    ioctl_t  io;
14
 
15
    io.handle   = fd;
16
    io.io_code  = request;
17
    io.input    = arg;
18
    io.inp_size = 64;
19
    io.output   = NULL;
20
    io.out_size = 0;
21
 
22
    return call_service(&io);
23
}
24
 
25
static EGLImageKHR px_create_image(EGLDisplay display, EGLContext context,
26
			 int width, int height, int stride, int name)
27
{
28
	EGLImageKHR image;
29
	EGLint attribs[] = {
30
		EGL_WIDTH, 0,
31
		EGL_HEIGHT, 0,
32
		EGL_DRM_BUFFER_STRIDE_MESA, 0,
33
		EGL_DRM_BUFFER_FORMAT_MESA,
34
		EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
35
		EGL_DRM_BUFFER_USE_MESA,
36
		EGL_DRM_BUFFER_USE_SHARE_MESA |
37
		    EGL_DRM_BUFFER_USE_SCANOUT_MESA,
38
		EGL_NONE
39
	};
40
	attribs[1] = width;
41
	attribs[3] = height;
42
	attribs[5] = stride/4;
43
 
44
    printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__,
45
           width, height, stride, name);
46
 
47
	image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA,
48
						 (void *) (uintptr_t)name, attribs);
49
 
50
	return image;
51
}
52
 
53
static GLint create_shader(GLenum type, const char *source)
54
{
55
	GLint ok;
56
    GLint shader;
57
 
58
    shader = glCreateShader(type);
59
    if(shader == 0)
60
        goto err;
61
 
62
    glShaderSource(shader, 1, (const GLchar **) &source, NULL);
63
    glCompileShader(shader);
64
    glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
65
	if (!ok) {
66
		GLchar *info;
67
		GLint size;
68
 
69
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
70
		info = malloc(size);
71
 
72
        glGetShaderInfoLog(shader, size, NULL, info);
73
		printf("Failed to compile %s: %s\n",
74
                type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
75
		printf("Program source:\n%s", source);
76
		printf("GLSL compile failure\n");
77
        free(info);
78
        glDeleteProgram(shader);
79
        shader = 0;
80
	}
81
err:
82
    return shader;
83
}
84
 
85
 
86
struct render* create_render(EGLDisplay dpy, EGLSurface surface, int dx, int dy)
87
{
88
    const char *vs_src =
89
	    "attribute vec4 v_position;\n"
90
	    "attribute vec4 v_texcoord0;\n"
91
	    "varying vec2 source_texture;\n"
92
	    "void main()\n"
93
	    "{\n"
94
	    "	gl_Position = v_position;\n"
95
	    "	source_texture = v_texcoord0.xy;\n"
96
	    "}\n";
97
 
98
	const char *fs_src =
99
//	    "precision mediump float;\n"
100
	    "varying vec2 source_texture;\n"
101
	    "uniform sampler2D sampler;\n"
102
	    "void main()\n"
103
	    "{\n"
104
	    "   vec3 cg = texture2D(sampler, source_texture).rgb;\n"
105
	    "   gl_FragColor = vec4(cg.r,cg.g,cg.b,1.0);\n"
106
	    "}\n";
107
    EGLint config_attribs[14];
108
    EGLConfig config;
109
    EGLint num_configs;
110
 
111
    EGLContext context;
112
 
113
    struct drm_i915_fb_info fb;
114
    GLint  vs_shader, fs_shader;
115
    GLenum status;
116
    GLint ret;
117
    int fd;
118
    struct render *render;
119
 
120
 
121
    fd = get_service("DISPLAY");
122
 
123
    memset(&fb, 0, sizeof(fb));
124
    ret = drm_ioctl(fd, SRV_FBINFO, &fb);
125
    if( ret != 0 )
126
    {   printf("failed to get framebuffer info\n");
127
        goto err;
128
    };
129
 
130
    render = (struct render*)malloc(sizeof(struct render));
131
    if(render == NULL)
132
        goto err;
133
 
134
    render->fd  = fd;
135
    render->dpy = dpy;
136
    render->dx  = dx;
137
    render->dy  = dy;
138
 
139
    if(!eglQuerySurface(dpy, surface, EGL_WIDTH, &render->width))
140
        goto err1;
141
 
142
    if(!eglQuerySurface(dpy, surface, EGL_HEIGHT, &render->height))
143
        goto err1;
144
 
145
    render->scr_width  = fb.width;
146
    render->scr_height = fb.height;
147
 
148
    render->front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_FRONT);
149
    if(render->front == EGL_NO_IMAGE_KHR)
150
        goto err1;
151
 
152
    render->back  = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK);
153
    if( render->back == EGL_NO_IMAGE_KHR)
154
        goto err2;
155
 
156
 
157
    context = eglGetCurrentContext();
158
 
159
    config_attribs[0] = EGL_RED_SIZE;
160
    config_attribs[1] = 1;
161
    config_attribs[2] = EGL_GREEN_SIZE;
162
    config_attribs[3] = 1;
163
    config_attribs[4] = EGL_BLUE_SIZE;
164
    config_attribs[5] = 1;
165
    config_attribs[6] = EGL_DEPTH_SIZE;
166
    config_attribs[7] = 1;
167
 
168
    config_attribs[8] = EGL_SURFACE_TYPE;
169
    config_attribs[9] = EGL_WINDOW_BIT;
170
 
171
    config_attribs[10] = EGL_RENDERABLE_TYPE;
172
    config_attribs[11] = EGL_OPENGL_BIT;
173
    config_attribs[12] = EGL_NONE;
174
 
175
    if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs)
176
    {
177
        printf("failed to choose a config");
178
        goto err3;
179
    }
180
 
181
    render->context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
182
    if (!context)
183
    {
184
        printf("failed to create context");
185
        goto err3;
186
    };
187
 
188
    if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context))
189
    {
190
        printf("failed to make window current");
191
        goto err4;
192
    };
193
 
194
 
195
    glGenTextures(2, render->tx_buffers);
196
    if(glGetError() != GL_NO_ERROR)
197
       goto err5;
198
 
199
    glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_FRONT]);
200
    if(glGetError() != GL_NO_ERROR)
201
       goto err6;
202
 
203
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
204
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
205
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->front);
206
    if(glGetError() != GL_NO_ERROR)
207
       goto err6;
208
 
209
    glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_BACK]);
210
    if(glGetError() != GL_NO_ERROR)
211
       goto err6;
212
 
213
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
214
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
215
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->back);
216
    if(glGetError() != GL_NO_ERROR)
217
       goto err6;
218
 
219
    glBindTexture(GL_TEXTURE_2D, 0);
220
 
221
    render->back_buffer = EGL_DRM_BUFFER_BACK;
222
 
223
 
224
    render->screen = px_create_image(dpy,context,fb.width,fb.height,
225
                                     fb.pitch,fb.name);
226
    if(render->screen == EGL_NO_IMAGE_KHR)
227
        goto err6;
228
 
229
    glGenTextures(1, &render->tx_screen);
230
    if(glGetError() != GL_NO_ERROR)
231
       goto err6;
232
 
233
    glBindTexture(GL_TEXTURE_2D, render->tx_screen);
234
    if(glGetError() != GL_NO_ERROR)
235
       goto err7;
236
 
237
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
238
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
239
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->screen);
240
    if(glGetError() != GL_NO_ERROR)
241
       goto err7;
242
 
243
    glBindTexture(GL_TEXTURE_2D, 0);
244
 
245
    glGenFramebuffers(1, &render->framebuffer);
246
    if(glGetError() != GL_NO_ERROR)
247
       goto err8;
248
 
249
    glBindFramebuffer(GL_FRAMEBUFFER, render->framebuffer);
250
    if(glGetError() != GL_NO_ERROR)
251
       goto err9;
252
 
253
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
254
                           GL_TEXTURE_2D, render->tx_screen,0);
255
 
256
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
257
    if (status != GL_FRAMEBUFFER_COMPLETE)
258
    {
259
        const char *str;
260
        switch (status)
261
        {
262
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
263
                 str = "incomplete attachment";
264
                 break;
265
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
266
                str = "incomplete/missing attachment";
267
                break;
268
            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
269
                str = "incomplete draw buffer";
270
                break;
271
            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
272
                str = "incomplete read buffer";
273
                break;
274
            case GL_FRAMEBUFFER_UNSUPPORTED:
275
                str = "unsupported";
276
                break;
277
            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
278
                str = "incomplete multiple";
279
                break;
280
            default:
281
                str = "unknown error";
282
                break;
283
        }
284
        printf("destination is framebuffer incomplete: %s [%#x]\n", str, status);
285
        goto err9;
286
    }
287
 
288
    glViewport(0, 0, render->scr_width, render->scr_height);
289
    glMatrixMode(GL_PROJECTION);
290
	glLoadIdentity();
291
	glMatrixMode(GL_MODELVIEW);
292
	glLoadIdentity();
293
 
294
    render->blit_prog = glCreateProgram();
295
    if(render->blit_prog == 0)
296
        goto err9;
297
 
298
    vs_shader = create_shader(GL_VERTEX_SHADER,vs_src);
299
    if(vs_shader == 0)
300
        goto err10;
301
 
302
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src);
303
    if(fs_shader == 0)
304
        goto err11;
305
 
306
    glAttachShader(render->blit_prog, vs_shader);
307
    glAttachShader(render->blit_prog, fs_shader);
308
    glBindAttribLocation(render->blit_prog, 0, "v_position");
309
    glBindAttribLocation(render->blit_prog, 1, "v_texcoord0");
310
 
311
    glLinkProgram(render->blit_prog);
312
    glGetProgramiv(render->blit_prog, GL_LINK_STATUS, &ret);
313
    if (!ret)
314
    {
315
        GLchar *info;
316
        GLint size;
317
 
318
        glGetProgramiv(render->blit_prog, GL_INFO_LOG_LENGTH, &size);
319
        info = malloc(size);
320
 
321
        glGetProgramInfoLog(render->blit_prog, size, NULL, info);
322
        printf("Failed to link: %s\n", info);
323
        printf("GLSL link failure\n");
324
        free(info);
325
    }
326
 
327
    render->sampler = glGetUniformLocation(render->blit_prog,"sampler");
328
 
329
    eglMakeCurrent(dpy, surface, surface, context);
330
 
331
    return render;
332
 
333
err11:
334
    glDeleteShader(vs_shader);
335
err10:
336
    glDeleteProgram(render->blit_prog);
337
err9:
338
    glDeleteFramebuffers(1, &render->framebuffer);
339
err8:
340
    eglDestroyImageKHR(dpy, render->screen);
341
err7:
342
    glDeleteTextures(1, &render->tx_screen);
343
err6:
344
    glDeleteTextures(2, render->tx_buffers);
345
err5:
346
    eglMakeCurrent(dpy, surface, surface, context);
347
err4:
348
    eglDestroyContext(dpy, render->context);
349
err3:
350
    eglDestroyImageKHR(dpy, render->back);
351
err2:
352
    eglDestroyImageKHR(dpy, render->front);
353
err1:
354
    free(render);
355
err:
356
    return NULL;
357
};
358