Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4768 Serge 1
#include 
2
#include 
3
#include 
4
#include 
5
 
6
#include "render.h"
7
#include 
8
#include 
9
 
10
void create_mask(struct render *render);
11
 
12
static int drm_ioctl(int fd, unsigned long request, void *arg)
13
{
14
    ioctl_t  io;
15
 
16
    io.handle   = fd;
17
    io.io_code  = request;
18
    io.input    = arg;
19
    io.inp_size = 64;
20
    io.output   = NULL;
21
    io.out_size = 0;
22
 
23
    return call_service(&io);
24
}
25
 
26
static EGLImageKHR px_create_image(EGLDisplay display, EGLContext context,
27
			 int width, int height, int stride, int name)
28
{
29
	EGLImageKHR image;
30
	EGLint attribs[] = {
31
		EGL_WIDTH, 0,
32
		EGL_HEIGHT, 0,
33
		EGL_DRM_BUFFER_STRIDE_MESA, 0,
34
		EGL_DRM_BUFFER_FORMAT_MESA,
35
		EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
36
		EGL_DRM_BUFFER_USE_MESA,
37
		EGL_DRM_BUFFER_USE_SHARE_MESA |
38
		    EGL_DRM_BUFFER_USE_SCANOUT_MESA,
39
		EGL_NONE
40
	};
41
	attribs[1] = width;
42
	attribs[3] = height;
43
	attribs[5] = stride/4;
44
 
45
    printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__,
46
           width, height, stride, name);
47
 
48
	image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA,
49
						 (void *) (uintptr_t)name, attribs);
50
 
51
	return image;
52
}
53
 
54
static GLint create_shader(GLenum type, const char *source)
55
{
56
	GLint ok;
57
    GLint shader;
58
 
59
    shader = glCreateShader(type);
60
    if(shader == 0)
61
        goto err;
62
 
63
    glShaderSource(shader, 1, (const GLchar **) &source, NULL);
64
    glCompileShader(shader);
65
    glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
66
	if (!ok) {
67
		GLchar *info;
68
		GLint size;
69
 
70
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
71
		info = malloc(size);
72
 
73
        glGetShaderInfoLog(shader, size, NULL, info);
74
		printf("Failed to compile %s: %s\n",
75
                type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
76
		printf("Program source:\n%s", source);
77
		printf("GLSL compile failure\n");
78
        free(info);
79
        glDeleteShader(shader);
80
        shader = 0;
81
	}
82
err:
83
    return shader;
84
}
85
 
86
 
87
struct render* create_render(EGLDisplay dpy, EGLSurface surface, int dx, int dy)
88
{
89
    const char *vs_src =
90
	    "attribute vec4 v_position;\n"
91
	    "attribute vec4 v_texcoord0;\n"
92
	    "varying vec2 source_texture;\n"
93
        "void main()\n"
94
	    "{\n"
95
	    "	gl_Position = v_position;\n"
96
	    "	source_texture = v_texcoord0.xy;\n"
97
	    "}\n";
98
 
99
    const char *fs_i965 =
100
	    "varying vec2 source_texture;\n"
101
        "uniform sampler2D sampler_src;\n"
102
        "uniform sampler2D sampler_mask;\n"
103
	    "void main()\n"
104
	    "{\n"
105
        "   float ca = texture2D(sampler_mask, source_texture).r;\n"
106
        "   gl_FragColor = vec4(texture2D(sampler_src, source_texture).rgb, ca);\n"
107
	    "}\n";
108
 
109
    const char *fs_i915 =
110
        "varying vec2 source_texture;\n"
111
        "uniform sampler2D sampler_src;\n"
112
        "uniform sampler2D sampler_mask;\n"
113
        "void main()\n"
114
        "{\n"
115
        "   float ca = texture2D(sampler_mask, source_texture).a;\n"
116
        "   gl_FragColor = vec4(texture2D(sampler_src, source_texture).rgb, ca);\n"
117
        "}\n";
118
 
119
    EGLint config_attribs[14];
120
    EGLConfig config;
121
    EGLint num_configs;
122
 
123
    EGLContext context;
124
 
125
    struct drm_i915_fb_info fb;
126
    GLint  vs_shader, fs_shader;
127
    GLenum status;
128
    GLint ret;
129
    int fd;
130
    struct render *render;
131
    char *drv_name;
132
    const char *fs_src;
133
 
134
 
135
    fd = get_service("DISPLAY");
136
 
137
    memset(&fb, 0, sizeof(fb));
138
    ret = drm_ioctl(fd, SRV_FBINFO, &fb);
139
    if( ret != 0 )
140
    {   printf("failed to get framebuffer info\n");
141
        goto err;
142
    };
143
 
144
    render = (struct render*)malloc(sizeof(struct render));
145
    if(render == NULL)
146
        goto err;
147
 
148
    render->fd  = fd;
149
    render->dpy = dpy;
150
    render->dx  = dx;
151
    render->dy  = dy;
152
 
153
    if(!eglQuerySurface(dpy, surface, EGL_WIDTH, &render->width))
154
        goto err1;
155
 
156
    if(!eglQuerySurface(dpy, surface, EGL_HEIGHT, &render->height))
157
        goto err1;
158
 
159
    render->scr_width  = fb.width;
160
    render->scr_height = fb.height;
161
 
162
    render->front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_FRONT);
163
    if(render->front == EGL_NO_IMAGE_KHR)
164
        goto err1;
165
 
166
    render->back  = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK);
167
    if( render->back == EGL_NO_IMAGE_KHR)
168
        goto err2;
169
 
170
 
171
    context = eglGetCurrentContext();
172
 
173
    config_attribs[0] = EGL_RED_SIZE;
174
    config_attribs[1] = 1;
175
    config_attribs[2] = EGL_GREEN_SIZE;
176
    config_attribs[3] = 1;
177
    config_attribs[4] = EGL_BLUE_SIZE;
178
    config_attribs[5] = 1;
179
    config_attribs[6] = EGL_DEPTH_SIZE;
180
    config_attribs[7] = 1;
181
 
182
    config_attribs[8] = EGL_SURFACE_TYPE;
183
    config_attribs[9] = EGL_WINDOW_BIT;
184
 
185
    config_attribs[10] = EGL_RENDERABLE_TYPE;
186
    config_attribs[11] = EGL_OPENGL_BIT;
187
    config_attribs[12] = EGL_NONE;
188
 
189
    if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs)
190
    {
191
        printf("failed to choose a config");
192
        goto err3;
193
    }
194
 
195
    render->context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
196
    if (!context)
197
    {
198
        printf("failed to create context");
199
        goto err3;
200
    };
201
 
202
    if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context))
203
    {
204
        printf("failed to make window current");
205
        goto err4;
206
    };
207
 
208
 
209
    glGenTextures(2, render->tx_buffers);
210
    if(glGetError() != GL_NO_ERROR)
211
       goto err5;
212
 
213
    glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_FRONT]);
214
    if(glGetError() != GL_NO_ERROR)
215
       goto err6;
216
 
217
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
218
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
219
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->front);
220
    if(glGetError() != GL_NO_ERROR)
221
       goto err6;
222
 
223
    glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_BACK]);
224
    if(glGetError() != GL_NO_ERROR)
225
       goto err6;
226
 
227
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
228
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
229
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->back);
230
    if(glGetError() != GL_NO_ERROR)
231
       goto err6;
232
 
233
    glBindTexture(GL_TEXTURE_2D, 0);
234
 
235
    render->back_buffer = EGL_DRM_BUFFER_FRONT;
236
 
237
    render->screen = px_create_image(dpy,context,fb.width,fb.height,
238
                                     fb.pitch,fb.name);
239
    if(render->screen == EGL_NO_IMAGE_KHR)
240
        goto err6;
241
 
242
    glGenTextures(1, &render->tx_screen);
243
    if(glGetError() != GL_NO_ERROR)
244
       goto err6;
245
 
246
    glBindTexture(GL_TEXTURE_2D, render->tx_screen);
247
    if(glGetError() != GL_NO_ERROR)
248
       goto err7;
249
 
250
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
251
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
252
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->screen);
253
    if(glGetError() != GL_NO_ERROR)
254
       goto err7;
255
 
256
    glBindTexture(GL_TEXTURE_2D, 0);
257
 
258
    create_mask(render);
259
 
260
    glGenFramebuffers(1, &render->framebuffer);
261
    if(glGetError() != GL_NO_ERROR)
262
       goto err8;
263
 
264
    glBindFramebuffer(GL_FRAMEBUFFER, render->framebuffer);
265
    if(glGetError() != GL_NO_ERROR)
266
       goto err9;
267
 
268
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
269
                           GL_TEXTURE_2D, render->tx_screen,0);
270
 
271
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
272
    if (status != GL_FRAMEBUFFER_COMPLETE)
273
    {
274
        const char *str;
275
        switch (status)
276
        {
277
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
278
                 str = "incomplete attachment";
279
                 break;
280
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
281
                str = "incomplete/missing attachment";
282
                break;
283
            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
284
                str = "incomplete draw buffer";
285
                break;
286
            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
287
                str = "incomplete read buffer";
288
                break;
289
            case GL_FRAMEBUFFER_UNSUPPORTED:
290
                str = "unsupported";
291
                break;
292
            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
293
                str = "incomplete multiple";
294
                break;
295
            default:
296
                str = "unknown error";
297
                break;
298
        }
299
        printf("destination is framebuffer incomplete: %s [%#x]\n", str, status);
300
        goto err9;
301
    }
302
 
303
    glViewport(0, 0, render->scr_width, render->scr_height);
304
    glMatrixMode(GL_PROJECTION);
305
	glLoadIdentity();
306
	glMatrixMode(GL_MODELVIEW);
307
	glLoadIdentity();
308
 
309
    drv_name = (char*)glGetString(0x1F04);
310
    printf("Render: %s\n", drv_name);
311
 
312
    if(strstr(drv_name, "i965"))
313
        fs_src = fs_i965;
314
    else if(strstr(drv_name, "i915"))
315
        fs_src = fs_i915;
316
    else fs_src = NULL;
317
 
318
    render->blit_prog = glCreateProgram();
319
    if(render->blit_prog == 0)
320
        goto err9;
321
 
322
    vs_shader = create_shader(GL_VERTEX_SHADER,vs_src);
323
    if(vs_shader == 0)
324
        goto err10;
325
 
326
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src);
327
    if(fs_shader == 0)
328
        goto err11;
329
 
330
    glAttachShader(render->blit_prog, vs_shader);
331
    glAttachShader(render->blit_prog, fs_shader);
332
    glBindAttribLocation(render->blit_prog, 0, "v_position");
333
    glBindAttribLocation(render->blit_prog, 1, "v_texcoord0");
334
 
335
    glLinkProgram(render->blit_prog);
336
    glGetProgramiv(render->blit_prog, GL_LINK_STATUS, &ret);
337
    if (!ret)
338
    {
339
        GLchar *info;
340
        GLint size;
341
 
342
        glGetProgramiv(render->blit_prog, GL_INFO_LOG_LENGTH, &size);
343
        info = malloc(size);
344
 
345
        glGetProgramInfoLog(render->blit_prog, size, NULL, info);
346
        printf("Failed to link: %s\n", info);
347
        printf("GLSL link failure\n");
348
        free(info);
349
        goto err12;
350
    }
351
 
352
    render->sampler = glGetUniformLocation(render->blit_prog,"sampler_src");
353
    render->sm_mask = glGetUniformLocation(render->blit_prog,"sampler_mask");
354
 
355
    glUseProgram(render->blit_prog);
356
    glUniform1i(render->sampler, 0);
357
    glUniform1i(render->sm_mask, 1);
358
 
359
    glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),render->vertices);
360
    glEnableVertexAttribArray(0);
361
 
362
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),render->tc_src);
363
    glEnableVertexAttribArray(1);
364
 
365
    render->tc_src[0]    = 0.0;
366
    render->tc_src[1]    = 0.0;
367
    render->tc_src[1*2]  = 1.0;
368
    render->tc_src[1*2+1]= 0.0;
369
    render->tc_src[2*2]  = 1.0;
370
    render->tc_src[2*2+1]= 1.0;
371
    render->tc_src[3*2]  = 0.0;
372
    render->tc_src[3*2+1]= 1.0;
373
 
374
    glEnable(GL_BLEND);
375
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
376
 
377
    glActiveTexture(GL_TEXTURE1);
378
    glBindTexture(GL_TEXTURE_2D, render->tx_mask);
379
    glTexParameteri(GL_TEXTURE_2D,
380
                  GL_TEXTURE_MIN_FILTER,
381
                  GL_NEAREST);
382
    glTexParameteri(GL_TEXTURE_2D,
383
                  GL_TEXTURE_MAG_FILTER,
384
                  GL_NEAREST);
385
 
386
    eglMakeCurrent(dpy, surface, surface, context);
387
 
388
    return render;
389
 
390
err12:
391
    glDeleteShader(fs_shader);
392
err11:
393
    glDeleteShader(vs_shader);
394
err10:
395
    glDeleteProgram(render->blit_prog);
396
err9:
397
    glDeleteFramebuffers(1, &render->framebuffer);
398
err8:
399
    eglDestroyImageKHR(dpy, render->screen);
400
err7:
401
    glDeleteTextures(1, &render->tx_screen);
402
err6:
403
    glDeleteTextures(2, render->tx_buffers);
404
err5:
405
    eglMakeCurrent(dpy, surface, surface, context);
406
err4:
407
    eglDestroyContext(dpy, render->context);
408
err3:
409
    eglDestroyImageKHR(dpy, render->back);
410
err2:
411
    eglDestroyImageKHR(dpy, render->front);
412
err1:
413
    free(render);
414
err:
415
    return NULL;
416
};
417
 
418
 
419
void create_mask(struct render *render)
420
{
421
    struct drm_i915_gem_create create;
422
    struct drm_gem_close close;
423
    struct drm_gem_flink flink;
424
 
425
    struct drm_i915_gem_mmap mmap_arg;
426
    EGLint handle, stride;
427
    int winw, winh, pitch;
428
    void *data;
429
    int ret;
430
    GLuint mask_handle, mask_name;
431
    EGLImageKHR mask_image;
432
 
433
    glGenTextures(1, &render->tx_mask);
434
    if(glGetError() != GL_NO_ERROR)
435
       return;
436
 
437
    glBindTexture(GL_TEXTURE_2D, render->tx_mask);
438
    if(glGetError() != GL_NO_ERROR)
439
       goto err1;
440
 
441
    pitch = (render->width+15) & ~15;
442
 
443
    create.size = pitch *render->height;
444
    create.handle = 0;
445
    ret = drm_ioctl(render->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
446
    if(ret != 0)
447
        goto err1;
448
 
449
    mask_handle = create.handle;
450
    flink.handle = create.handle;
451
    ret = drm_ioctl(render->fd, DRM_IOCTL_GEM_FLINK, &flink);
452
    if (ret != 0)
453
        goto err2;
454
 
455
    mask_name = flink.name;
456
 
457
    printf("create mask bo handle %d name %d\n", create.handle, flink.name);
458
 
459
    EGLint attribs[] = {
460
        EGL_WIDTH, 0,
461
        EGL_HEIGHT, 0,
462
        EGL_DRM_BUFFER_STRIDE_MESA, 0,
463
        EGL_DRM_BUFFER_FORMAT_MESA,
464
        EGL_DRM_BUFFER_FORMAT_R8_MESA,
465
        EGL_DRM_BUFFER_USE_MESA,
466
        EGL_DRM_BUFFER_USE_SHARE_MESA,
467
        EGL_NONE
468
    };
469
    attribs[1] = pitch;
470
    attribs[3] = render->height;
471
    attribs[5] = pitch;
472
 
473
    mask_image = eglCreateImageKHR(render->dpy, render->context, EGL_DRM_BUFFER_MESA,
474
                         (void *) (uintptr_t)mask_name, attribs);
475
    printf("create mask image %p\n", mask_image);
476
    if(mask_image == NULL)
477
        goto err2;
478
 
479
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
480
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
481
 
482
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mask_image);
483
 
484
    if(glGetError() != GL_NO_ERROR)
485
       goto err3;
486
 
487
    glBindTexture(GL_TEXTURE_2D, 0);
488
 
489
    mmap_arg.handle = mask_handle;
490
    mmap_arg.offset = 0;
491
    mmap_arg.size = pitch * render->height;
492
    if (drm_ioctl(render->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg))
493
    {
494
        printf("%s: failed to mmap image %p handle=%d, %d bytes, into CPU domain\n",
495
               __FUNCTION__, mask_image, mask_handle, pitch * render->height);
496
        goto err3;
497
    }
498
 
499
    render->mask_handle = mask_handle;
500
    render->mask_name   = mask_name;
501
    render->mask_buffer = (void *)(uintptr_t)mmap_arg.addr_ptr;
502
    render->mask_image = mask_image;
503
 
504
    return;
505
 
506
err3:
507
    eglDestroyImageKHR(render->dpy, mask_image);
508
err2:
509
    close.handle = mask_handle;
510
    (void)drm_ioctl(render->fd, DRM_IOCTL_GEM_CLOSE, &close);
511
    glBindTexture(GL_TEXTURE_2D, 0);
512
err1:
513
    glDeleteTextures(1, &render->tx_mask);
514
};