Subversion Repositories Kolibri OS

Rev

Rev 6142 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5371 serge 1
#include 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include "pixlib3.h"
7
#include "pixdriver.h"
8
#include "pxgl.h"
9
 
10
#define WIN_STATE_MINIMIZED  0x02
11
#define WIN_STATE_ROLLED     0x04
12
 
6137 serge 13
#define LINE()    printf("%s line %d\n", __FUNCTION__,__LINE__)
14
 
5371 serge 15
static int drm_ioctl(int fd, unsigned long request, void *arg)
16
{
17
    ioctl_t  io;
18
 
19
    io.handle   = fd;
20
    io.io_code  = request;
21
    io.input    = arg;
22
    io.inp_size = 64;
23
    io.output   = NULL;
24
    io.out_size = 0;
25
 
26
    return call_service(&io);
27
}
28
 
29
static EGLImageKHR px_create_image(struct render *px,void *name,GLuint tex, EGLint *attribs)
30
{
31
    EGLImageKHR image;
32
 
33
    image = eglCreateImageKHR(px->dpy, px->context,
34
                              EGL_DRM_BUFFER_MESA, name, attribs);
35
    if(image == NULL)
36
        goto err_0;
37
 
38
    glBindTexture(GL_TEXTURE_2D, tex);
39
    if(glGetError() != GL_NO_ERROR)
40
       goto err_1;
41
 
42
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
43
    if(glGetError() != GL_NO_ERROR)
44
       goto err_1;
45
 
5602 serge 46
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
47
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
5371 serge 48
 
49
    return image;
50
 
51
err_1:
52
    eglDestroyImageKHR(px->dpy, image);
53
err_0:
54
    return NULL;
55
};
56
 
57
static int update_fb(struct render *px, int name, int pitch)
58
{
59
    GLenum      status;
60
    EGLImageKHR screen;
61
 
62
    EGLint attribs[] = {
63
        EGL_WIDTH, px->scr_width,
64
        EGL_HEIGHT, px->scr_height,
65
        EGL_DRM_BUFFER_STRIDE_MESA, pitch/4,
66
        EGL_DRM_BUFFER_FORMAT_MESA,
67
        EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
68
        EGL_DRM_BUFFER_USE_MESA,
69
        EGL_DRM_BUFFER_USE_SHARE_MESA |
70
        EGL_DRM_BUFFER_USE_SCANOUT_MESA,
71
        EGL_NONE
72
    };
73
    char *errmsg;
74
 
75
    px->screen = px_create_image(px,(void*)name, px->texture[TEX_SCREEN], attribs);
76
    errmsg = "failed to create new screen image\n";
77
    if(px->screen == EGL_NO_IMAGE_KHR)
78
        goto err_0;
79
 
80
    px->screen = screen;
81
 
82
    glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
83
                       GL_TEXTURE_2D, px->texture[TEX_SCREEN],0);
84
 
85
    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
86
    if (status != GL_FRAMEBUFFER_COMPLETE)
87
    {
88
        const char *str;
89
        switch (status)
90
        {
91
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
92
                str = "incomplete attachment";
93
                break;
94
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
95
                str = "incomplete/missing attachment";
96
                break;
97
            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
98
                str = "incomplete draw buffer";
99
                break;
100
            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
101
                str = "incomplete read buffer";
102
                break;
103
            case GL_FRAMEBUFFER_UNSUPPORTED:
104
                str = "unsupported";
105
                break;
106
            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
107
                str = "incomplete multiple";
108
                break;
109
            default:
110
                str = "unknown error";
111
                break;
112
        }
113
        DBG("destination framebuffer incomplete: %s [%#x]\n", str, status);
114
 
115
        return -1;
116
    };
117
 
118
    DBG("framebuffer changed successfull\n");
119
 
120
    glViewport(0, 0, px->scr_width, px->scr_height);
121
 
122
    return 0;
123
 
124
err_0:
125
    DBG("%s %s\n", __FUNCTION__, errmsg);
126
 
127
    return -1;
128
};
129
 
130
 
131
 
132
static void *px_create_obj(struct render *px, size_t size,
133
                           GLuint *handle, GLuint *name)
134
{
135
    struct drm_i915_gem_create create;
136
    struct drm_i915_gem_mmap mmap_arg;
137
    struct drm_gem_close close;
138
    struct drm_gem_flink flink;
139
 
140
    create.size   = size;
141
    create.handle = 0;
142
 
143
    if(drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_CREATE, &create))
144
        goto err_0;
145
 
146
    *handle      = create.handle;
147
    flink.handle = create.handle;
148
    if (drm_ioctl(px->fd, DRM_IOCTL_GEM_FLINK, &flink))
149
        goto err_1;
150
 
151
    *name = flink.name;
152
 
153
    mmap_arg.handle = *handle;
154
    mmap_arg.offset = 0;
155
    mmap_arg.size   = size;
156
    if (drm_ioctl(px->fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg))
157
    {
158
        DBG("%s: failed to mmap bitmap handle=%d, %d bytes, into CPU domain\n",
159
               __FUNCTION__, *handle, size);
160
        goto err_1;
161
    };
162
 
163
    return (void*)(uintptr_t)mmap_arg.addr_ptr;
164
 
165
err_1:
166
    close.handle = *handle;
167
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
168
err_0:
169
    return NULL;
170
};
171
 
172
static int px_create_bitmap(struct render *px, struct bitmap *bitmap,
173
                            size_t size, EGLint format)
174
{
175
    struct drm_gem_close close;
176
    EGLint attribs[] = {
177
        EGL_WIDTH, bitmap->width,
178
        EGL_HEIGHT, bitmap->height,
179
        EGL_DRM_BUFFER_STRIDE_MESA, 0,
180
        EGL_DRM_BUFFER_FORMAT_MESA,
181
        format,
182
        EGL_DRM_BUFFER_USE_MESA,
183
        EGL_DRM_BUFFER_USE_SHARE_MESA,
184
        EGL_NONE
185
    };
186
 
187
    bitmap->buffer = px_create_obj(px, size, &bitmap->handle, &bitmap->name);
188
    if(bitmap->buffer == NULL)
189
        goto err_0;
190
 
191
    switch(format)
192
    {
193
        case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
194
            attribs[5] = bitmap->pitch/4;
195
            break;
196
        case EGL_DRM_BUFFER_FORMAT_R8_MESA:
197
            attribs[5] = bitmap->pitch;
198
            break;
199
        default:
200
            DBG("%s invalid format %x\n",
201
                    __FUNCTION__, format);
202
            goto err_1;
203
    }
204
 
205
    bitmap->image = px_create_image(px,(void*)bitmap->name,
206
                                    bitmap->tex, attribs);
207
    if(bitmap->image == NULL)
208
        goto err_1;
209
 
210
    DBG("create bitmap:%p %dx%d pitch:%d\n"
211
           "KHRimage:%p gl_tex:%d handle:%d name:%d\n"
212
           "mapped at %x\n",
213
            bitmap, bitmap->width, bitmap->height, bitmap->pitch,
214
            bitmap->image, bitmap->tex, bitmap->handle, bitmap->name,
215
            bitmap->buffer);
216
 
217
    return 0;
218
 
219
err_1:
220
    user_free(bitmap->buffer);
221
    close.handle = bitmap->handle;
222
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
223
err_0:
224
    return -1;
225
}
226
 
227
 
228
static int create_mask(struct render *px)
229
{
230
    struct drm_i915_mask_update update;
231
    int    pitch;
232
 
233
    pitch = (px->width+15) & ~15;
234
 
235
    px->mask.width  = px->width;
236
    px->mask.height = px->height;
237
    px->mask.pitch  = pitch;
238
    px->mask.tex    = px->texture[TEX_MASK];
239
    px->mask_size   = pitch * px->height;
240
 
241
    if(px_create_bitmap(px, &px->mask, px->mask_size,
242
                         EGL_DRM_BUFFER_FORMAT_R8_MESA) == 0)
243
    {
244
        update.handle = px->mask.handle;
245
        update.dx     = px->dx;
246
        update.dy     = px->dy;
247
        update.width  = px->width;
248
        update.height = px->height;
249
        update.bo_pitch = (px->width+15) & ~15;
250
        update.bo_map = (int)px->mask.buffer;
251
        update.forced = 1;
252
        drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
253
        return 0;
254
    };
255
    return -1;
256
};
257
 
258
 
259
static int update_mask(struct render *px)
260
{
261
    struct drm_gem_close close;
262
    EGLint attribs[] = {
263
        EGL_WIDTH, 0,
264
        EGL_HEIGHT, 0,
265
        EGL_DRM_BUFFER_STRIDE_MESA, 0,
266
        EGL_DRM_BUFFER_FORMAT_MESA,
267
        EGL_DRM_BUFFER_FORMAT_R8_MESA,
268
        EGL_DRM_BUFFER_USE_MESA,
269
        EGL_DRM_BUFFER_USE_SHARE_MESA,
270
        EGL_NONE
271
    };
272
    unsigned int size, pitch;
273
 
274
    eglDestroyImageKHR(px->dpy, px->mask.image);
275
 
276
    pitch = (px->width+15) & ~15;
277
    size = pitch*px->height;
278
 
279
    if(size > px->mask_size)
280
    {
281
        user_free(px->mask.buffer);
282
        close.handle = px->mask.handle;
283
        drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
284
 
285
        px->mask_size = size;
286
 
287
        px->mask.buffer = px_create_obj(px, px->mask_size,
288
                                      &px->mask.handle, &px->mask.name);
289
        if(px->mask.buffer == 0)
290
            goto err_0;
291
    };
292
 
293
    attribs[1] = px->width;
294
    attribs[3] = px->height;
295
    attribs[5] = pitch;
296
 
297
    px->mask.image = px_create_image(px,(void*)px->mask.name,
298
                                     px->mask.tex, attribs);
299
    if(px->mask.image == NULL)
300
        goto err_1;
301
 
302
    DBG("create mask w:%d h:%d pitch:%d\n"
303
        "KHRimage:%p gl_tex:%d handle:%d name:%d\n"
304
        "mapped at %x\n",
305
         px->width, px->height,
306
         pitch, px->mask.image, px->texture[TEX_MASK],
307
         px->mask.handle, px->mask.name, px->mask.buffer);
308
 
309
    return 0;
310
 
311
err_1:
312
    user_free(px->mask.buffer);
313
    close.handle = px->mask.handle;
314
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
315
err_0:
316
    return -1;
317
};
318
 
6137 serge 319
static GLint create_shader(GLenum type, const char *source)
5371 serge 320
{
6137 serge 321
    GLint ok;
322
    GLint shader;
323
 
324
    shader = glCreateShader(type);
325
    if(shader == 0)
326
        goto err;
327
 
328
    glShaderSource(shader, 1, (const GLchar **) &source, NULL);
329
    glCompileShader(shader);
330
    glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
331
    if (!ok) {
332
        GLchar *info;
333
        GLint size;
334
 
335
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
336
        info = malloc(size);
337
 
338
        glGetShaderInfoLog(shader, size, NULL, info);
339
        DBG("Failed to compile %s: %s\n",
340
                type == GL_FRAGMENT_SHADER ? "FS" : "VS",info);
341
        DBG("Program source:\n%s", source);
342
        DBG("GLSL compile failure\n");
343
        free(info);
344
        glDeleteShader(shader);
345
        shader = 0;
346
    };
347
 
348
    DBG("create shader %d\n", shader);
349
err:
350
    return shader;
351
}
352
 
353
static GLuint create_rgba_shader(struct shader *shader)
354
{
5371 serge 355
    const char *vs_src =
356
        "attribute vec4 v_position;\n"
357
        "attribute vec4 v_texcoord0;\n"
6137 serge 358
        "varying vec2 tex_coord;\n"
5371 serge 359
        "void main()\n"
360
        "{\n"
361
        "   gl_Position = v_position;\n"
6137 serge 362
        "   tex_coord   = v_texcoord0.xy;\n"
5371 serge 363
        "}\n";
364
 
6334 serge 365
    const char *fs_i965 =
6137 serge 366
        "uniform sampler2D tex_rgba;\n"
367
        "uniform sampler2D tex_mask;\n"
368
        "varying vec2 tex_coord;\n"
5371 serge 369
        "void main()\n"
370
        "{\n"
6137 serge 371
        "   float ca = texture2D(tex_mask, tex_coord).r;\n"
372
        "   gl_FragColor = vec4(texture2D(tex_rgba, tex_coord).rgb, ca);\n"
5371 serge 373
        "}\n";
374
 
6334 serge 375
    const char *fs_i915 =
376
        "uniform sampler2D tex_rgba;\n"
377
        "uniform sampler2D tex_mask;\n"
378
        "varying vec2 tex_coord;\n"
379
        "void main()\n"
380
        "{\n"
381
        "   float ca = texture2D(tex_mask, tex_coord).a;\n"
382
        "   gl_FragColor = vec4(texture2D(tex_rgba, tex_coord).rgb, ca);\n"
383
        "}\n";
384
 
6137 serge 385
    GLuint prog;
386
    GLint  vs_shader, fs_shader;
6334 serge 387
    const char *fs_src;
388
    char *drv_name;
6137 serge 389
    int ret;
390
 
391
    prog = glCreateProgram();
392
    if(prog == 0)
393
        goto err;
394
 
395
    vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
396
    if(vs_shader == 0)
397
        goto err;
398
 
6334 serge 399
    drv_name = (char*)glGetString(0x1F04);
400
    printf("Render: %s\n", drv_name);
401
 
402
    if(strstr(drv_name, "i965"))
403
        fs_src = fs_i965;
404
    else if(strstr(drv_name, "i915"))
405
        fs_src = fs_i915;
406
    else fs_src = NULL;
407
 
408
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src);
6137 serge 409
    if(fs_shader == 0)
410
        goto err;
411
 
412
    glAttachShader(prog, vs_shader);
413
    glAttachShader(prog, fs_shader);
414
    glBindAttribLocation(prog, 0, "v_position");
415
    glBindAttribLocation(prog, 1, "v_texcoord0");
416
 
417
    glLinkProgram(prog);
418
    glGetProgramiv(prog, GL_LINK_STATUS, &ret);
419
    if (!ret)
420
    {
421
        GLchar *info;
422
        GLint size;
423
 
424
        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
425
        info = malloc(size);
426
 
427
        glGetProgramInfoLog(prog, size, NULL, info);
428
        DBG("Failed to link: %s\n", info);
429
        DBG("GLSL link failure\n");
430
        free(info);
431
        goto err;
432
    }
433
 
434
    shader->sampler0  = glGetUniformLocation(prog,"tex_rgba");
435
    shader->sm_mask   = glGetUniformLocation(prog,"tex_mask");
436
    shader->blit_prog = prog;
437
    return prog;
438
err:
439
    return 0;
440
}
441
 
442
static GLuint create_y_uv_shader(struct shader *shader)
443
{
444
    const char *vs_src =
445
        "attribute vec4 v_position;\n"
446
        "attribute vec4 v_texcoord0;\n"
447
        "varying vec2 tex_coord;\n"
448
        "void main()\n"
449
        "{\n"
450
        "   gl_Position = v_position;\n"
451
        "   tex_coord   = v_texcoord0.xy;\n"
452
        "}\n";
453
 
454
    const char *fs_y_uv =
455
        "uniform sampler2D tex_src_y;\n"
456
        "uniform sampler2D tex_src_uv;\n"
457
        "uniform sampler2D tex_mask;\n"
458
        "varying vec2 tex_coord;\n"
459
        "void main()\n"
460
        "{\n"
461
        "   float y = 1.16438356 * (texture2D(tex_src_y, tex_coord).x - 0.0625);\n"
462
        "   float u = texture2D(tex_src_uv, tex_coord).r - 0.5;\n"
463
        "   float v = texture2D(tex_src_uv, tex_coord).g - 0.5;\n"
464
        "   gl_FragColor.r = y + 1.59602678 * v;\n"          \
465
        "   gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n" \
466
        "   gl_FragColor.b = y + 2.01723214 * u;\n"          \
467
        "   gl_FragColor.a = texture2D(tex_mask, tex_coord).r;\n"
468
        "}\n";
469
 
470
    GLuint prog;
471
    GLint  vs_shader, fs_shader;
472
    int ret;
473
 
474
    prog = glCreateProgram();
475
    if(prog == 0)
476
        goto err;
477
 
478
    vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
479
    if(vs_shader == 0)
480
        goto err;
481
 
482
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_y_uv);
483
    if(fs_shader == 0)
484
        goto err;
485
 
486
    glAttachShader(prog, vs_shader);
487
    glAttachShader(prog, fs_shader);
488
    glBindAttribLocation(prog, 0, "v_position");
489
    glBindAttribLocation(prog, 1, "v_texcoord0");
490
 
491
    glLinkProgram(prog);
492
    glGetProgramiv(prog, GL_LINK_STATUS, &ret);
493
    if (!ret)
494
    {
495
        GLchar *info;
496
        GLint size;
497
 
498
        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
499
        info = malloc(size);
500
 
501
        glGetProgramInfoLog(prog, size, NULL, info);
502
        DBG("Failed to link: %s\n", info);
503
        DBG("GLSL link failure\n");
504
        free(info);
505
        goto err;
506
    }
507
 
508
    shader->sampler0  = glGetUniformLocation(prog,"tex_src_y");
509
    shader->sampler1  = glGetUniformLocation(prog,"tex_src_uv");
510
    shader->sm_mask   = glGetUniformLocation(prog,"tex_mask");
511
    shader->blit_prog = prog;
512
    return prog;
513
err:
514
    return 0;
515
}
516
 
517
static struct render* create_render(EGLDisplay dpy, EGLContext context, int dx, int dy, int w, int h)
518
{
519
 
5371 serge 520
    struct drm_i915_fb_info fb;
521
    struct render *px;
6137 serge 522
 
5371 serge 523
    int    ret;
524
 
525
    px = (struct render*)malloc(sizeof(struct render));
526
    if(px == NULL)
527
        goto err_0;
528
 
529
    px->fd  = get_service("DISPLAY");
530
 
531
    __builtin_memset(&fb, 0, sizeof(fb));
532
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
533
    {   DBG("failed to get framebuffer info\n");
534
        goto err_1;
535
    };
536
 
537
    px->dpy     = dpy;
538
    px->context = context;
539
    px->dx      = dx;
540
    px->dy      = dy;
541
    px->width   = w;
542
    px->height  = h;
543
    px->scr_width  = fb.width;
544
    px->scr_height = fb.height;
545
 
546
    glGenTextures(2, px->texture);
547
    if(glGetError() != GL_NO_ERROR)
548
       goto err_1;
549
 
550
    glGenFramebuffers(1, &px->framebuffer);
551
    if(glGetError() != GL_NO_ERROR)
552
       goto err_2;
553
 
554
    glBindFramebuffer(GL_FRAMEBUFFER, px->framebuffer);
555
    if(glGetError() != GL_NO_ERROR)
556
       goto err_3;
557
 
558
    if(update_fb(px, fb.name, fb.pitch))
559
       goto err_4;
560
 
561
    glMatrixMode(GL_PROJECTION);
562
    glLoadIdentity();
563
    glMatrixMode(GL_MODELVIEW);
564
    glLoadIdentity();
565
 
566
    if(create_mask(px))
567
        goto err_4;
568
 
6137 serge 569
    create_y_uv_shader(&px->shader_y_uv);
570
    create_rgba_shader(&px->shader_rgba);
5371 serge 571
 
572
    glEnableClientState(GL_VERTEX_ARRAY);
573
 
574
    glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->vertices);
575
    glEnableVertexAttribArray(0);
576
 
577
    glVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->tc_src);
578
    glEnableVertexAttribArray(1);
579
 
580
    glEnable(GL_BLEND);
581
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
582
 
583
    px->tc_src[0]    = 0.0;
584
    px->tc_src[1]    = 0.0;
585
    px->tc_src[1*2]  = 1.0;
586
    px->tc_src[1*2+1]= 0.0;
587
    px->tc_src[2*2]  = 1.0;
588
    px->tc_src[2*2+1]= 1.0;
589
    px->tc_src[3*2]  = 0.0;
590
    px->tc_src[3*2+1]= 1.0;
591
 
592
    DBG("create render framebuffer:%p %dx%d pitch:%d name %d\n",
593
        px->screen,fb.width, fb.height, fb.pitch, fb.name);
594
 
595
    return px;
596
 
597
err_4:
598
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
599
err_3:
600
    glDeleteFramebuffers(1, &px->framebuffer);
601
err_2:
602
    glDeleteTextures(2, px->texture);
603
err_1:
604
    free(px);
605
err_0:
606
    return NULL;
607
};
608
 
609
static struct render *px;
610
 
611
static bitmap_t *hw_create_bitmap(uint32_t width, uint32_t height)
612
{
613
    struct bitmap *bitmap;
614
 
615
    bitmap = malloc(sizeof(struct bitmap));
616
    if(bitmap == NULL)
617
        return NULL;
618
 
619
    glGenTextures(1, &bitmap->tex);
620
    if(glGetError() != GL_NO_ERROR)
621
       goto err_0;
622
 
623
    bitmap->width   = width;
624
    bitmap->height  = height;
625
    bitmap->pitch   = (width*4 + 15) & ~15;
626
 
627
    if(px_create_bitmap(px, bitmap, bitmap->pitch * bitmap->height,
628
                         EGL_DRM_BUFFER_FORMAT_ARGB32_MESA) == 0)
629
    {
630
        return bitmap;
631
    };
632
 
633
    glDeleteTextures(1, &bitmap->tex);
634
err_0:
635
    free(bitmap);
636
    return NULL;
637
};
638
 
6142 serge 639
static int hw_destroy_planar(planar_t *planar)
640
{
641
    glDeleteTextures(planar->num_planes, &planar->tex[0]);
642
 
643
    if(planar->image[2] != NULL)
644
        eglDestroyImageKHR(px->dpy, planar->image[2]);
645
    if(planar->image[1] != NULL)
646
        eglDestroyImageKHR(px->dpy, planar->image[1]);
647
    if(planar->image[0] != NULL)
648
        eglDestroyImageKHR(px->dpy, planar->image[0]);
649
    if(planar->planar_image != NULL)
650
        eglDestroyImageKHR(px->dpy, planar->planar_image);
651
    free(planar);
652
    return 0;
653
};
654
 
6115 serge 655
static planar_t* hw_create_planar(EGLint name, EGLint format, uint32_t width, uint32_t height,
656
                            uint32_t offset0, uint32_t pitch0,
657
                            uint32_t offset1, uint32_t pitch1,
658
                            uint32_t offset2, uint32_t pitch2)
659
{
660
    struct drm_gem_close close;
661
    planar_t *planar;
662
    EGLImageKHR img;
663
    int num_planes;
664
    int i;
665
 
666
    EGLint attribs[] = {
667
        EGL_WIDTH, width,
668
        EGL_HEIGHT,height,
669
        EGL_DRM_BUFFER_FORMAT_MESA, format,
670
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
671
        EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch0,
672
        EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
673
        EGL_DMA_BUF_PLANE1_PITCH_EXT, pitch1,
674
        EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
675
        EGL_DMA_BUF_PLANE2_PITCH_EXT, pitch2,
676
        EGL_NONE, EGL_NONE
677
    };
678
 
679
    switch (format)
680
    {
6137 serge 681
        case WL_DRM_FORMAT_NV12:
6115 serge 682
            num_planes = 2;
683
            break;
684
        case EGL_TEXTURE_Y_U_V_WL:
685
            num_planes = 3;
686
            break;
687
        case EGL_TEXTURE_Y_XUXV_WL:
688
            num_planes = 2;
689
            break;
690
        default:
691
            num_planes = 0;
692
    }
693
 
6137 serge 694
//    printf("%s num_planes %d\n", __FUNCTION__, num_planes);
695
 
6115 serge 696
    if(num_planes == 0)
6137 serge 697
        goto fail;
6115 serge 698
 
699
    planar = calloc(1, sizeof(struct planar));
700
    if(planar == NULL)
6137 serge 701
        goto fail;
6115 serge 702
 
703
    img = eglCreatePlanarImage(px->dpy, px->context, (EGLClientBuffer)name, attribs);
704
    if(img == NULL)
705
        goto err_0;
706
 
707
    planar->width  = width;
708
    planar->height = height;
709
    planar->name   = name;
6142 serge 710
    planar->num_planes = num_planes;
6115 serge 711
    planar->planar_image = img;
712
 
713
    planar->offset[0] = offset0;
714
    planar->offset[1] = offset1;
715
    planar->offset[2] = offset2;
716
 
717
    planar->pitch[0] = pitch0;
718
    planar->pitch[1] = pitch1;
719
    planar->pitch[2] = pitch2;
720
 
721
    glGenTextures(num_planes, &planar->tex[0]);
6142 serge 722
    if(glGetError() != GL_NO_ERROR)
723
       goto err_0;
6115 serge 724
 
725
    for(i = 0; i < num_planes; i++)
726
    {
6137 serge 727
        EGLImageKHR image;
6115 serge 728
        EGLint attr[3];
729
        attr[0] = EGL_WAYLAND_PLANE_WL;
730
        attr[1] = i;
731
        attr[2] = EGL_NONE;
732
 
6137 serge 733
        image = eglCreateImageKHR(px->dpy, px->context,
734
                                   EGL_WAYLAND_BUFFER_WL,(EGLClientBuffer)img, attr);
6142 serge 735
        if(image == NULL)
736
            goto err_1;
6115 serge 737
 
6137 serge 738
        planar->image[i] = image;
6115 serge 739
        glBindTexture(GL_TEXTURE_2D, planar->tex[i]);
6137 serge 740
        if(glGetError() != GL_NO_ERROR)
741
        {
6142 serge 742
            goto err_1;
6137 serge 743
        };
6115 serge 744
 
6137 serge 745
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
746
        if(glGetError() != GL_NO_ERROR)
747
        {
6142 serge 748
            goto err_1;
6137 serge 749
        }
750
 
6115 serge 751
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
752
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
753
    };
754
 
755
    return planar;
756
 
6142 serge 757
err_1:
758
    hw_destroy_planar(planar);
759
    return NULL;
760
 
6115 serge 761
err_0:
762
    free(planar);
6137 serge 763
fail:
6115 serge 764
    return NULL;
765
}
766
 
5371 serge 767
static int hw_destroy_bitmap(bitmap_t * bitmap)
768
{
769
    struct drm_gem_close close;
770
 
771
    glDeleteTextures(1, &bitmap->tex);
772
    eglDestroyImageKHR(px->dpy, bitmap->image);
773
    user_free(bitmap->buffer);
774
    close.handle = bitmap->handle;
775
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
776
    free(bitmap);
6142 serge 777
    return 0;
5371 serge 778
};
779
 
780
static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
781
{
782
    *pitch = bitmap->pitch;
783
 
784
    return bitmap->buffer;
785
};
786
 
787
static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
788
{
789
    return 0;
790
}
791
 
792
char proc_info[1024];
793
 
794
static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y,
795
                   uint32_t w, uint32_t h, int src_x, int src_y)
796
{
797
    struct drm_i915_mask_update update;
798
    struct drm_i915_fb_info fb;
799
 
800
    uint32_t winx, winy, winw, winh;
801
    uint8_t  state;
802
    float xscale, yscale;
803
    int r, b;
804
    float *vertices  = px->vertices;
805
 
806
    get_proc_info(proc_info);
807
 
808
    state  = *(uint8_t*)(proc_info+70);
809
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
810
        return;
811
 
812
    winx = *(uint32_t*)(proc_info+34);
813
    winy = *(uint32_t*)(proc_info+38);
814
    winw = *(uint32_t*)(proc_info+42)+1;
815
    winh = *(uint32_t*)(proc_info+46)+1;
816
 
817
    __builtin_memset(&fb, 0, sizeof(fb));
818
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
819
    {
820
        DBG("failed to get framebuffer info\n");
821
        return;
822
    };
823
 
824
    if( fb.width  != px->scr_width ||
825
        fb.height != px->scr_height )
826
    {
827
        px->scr_width  = fb.width;
828
        px->scr_height = fb.height;
829
 
830
        eglDestroyImageKHR(px->dpy, px->screen);
831
 
832
        if(update_fb(px, fb.name, fb.pitch))
833
            return;
834
    };
835
 
836
    update.handle = px->mask.handle;
837
    update.dx     = px->dx;
838
    update.dy     = px->dy;
839
    update.width  = px->width;
840
    update.height = px->height;
841
    update.bo_pitch = (px->width+15) & ~15;
842
    update.bo_map = (int)px->mask.buffer;
843
 
844
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
845
    {
846
        return;
847
    }
848
 
849
    xscale = 1.0/px->scr_width;
850
    yscale = 1.0/px->scr_height;
851
 
852
    r = winx + px->dx + px->width;
853
    b = winy + px->dy + px->height;
854
 
855
    float t0, t1, t2, t5;
856
 
857
//    render->tc_src[1*2]  = 1.0;
858
//    render->tc_src[2*2]  = 1.0;
859
//    render->tc_src[2*2+1]= 1.0;
860
//    render->tc_src[3*2+1]= 1.0;
861
 
862
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
863
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
864
 
865
    vertices[2 * 2] = t2;
866
    vertices[3 * 2] = t0;
867
 
868
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
869
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
870
    vertices[1*2+1] = t1;
871
    vertices[3*2+1] = t5;
872
 
6137 serge 873
    struct shader *shader = &px->shader_rgba;
874
 
875
    glUseProgram(shader->blit_prog);
876
    glUniform1i(shader->sampler0, 0);
877
    glUniform1i(shader->sm_mask, 1);
878
 
5371 serge 879
    glActiveTexture(GL_TEXTURE0);
880
    glBindTexture(GL_TEXTURE_2D, bitmap->tex);
881
 
882
    glActiveTexture(GL_TEXTURE1);
883
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
884
 
885
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
886
 
887
    glFlush();
888
 
889
    return;
890
};
891
 
6137 serge 892
static int hw_blit_planar(planar_t *planar, int dst_x, int dst_y,
893
                   uint32_t w, uint32_t h, int src_x, int src_y)
894
{
895
    struct drm_i915_mask_update update;
896
    struct drm_i915_fb_info fb;
897
 
898
    uint32_t winx, winy, winw, winh;
899
    uint8_t  state;
900
    float xscale, yscale;
901
    int r, b;
902
    float *vertices  = px->vertices;
903
 
904
    get_proc_info(proc_info);
905
 
906
    state  = *(uint8_t*)(proc_info+70);
907
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
908
        return;
909
 
910
    winx = *(uint32_t*)(proc_info+34);
911
    winy = *(uint32_t*)(proc_info+38);
912
    winw = *(uint32_t*)(proc_info+42)+1;
913
    winh = *(uint32_t*)(proc_info+46)+1;
914
 
915
    __builtin_memset(&fb, 0, sizeof(fb));
916
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
917
    {
918
        DBG("failed to get framebuffer info\n");
919
        return;
920
    };
921
 
922
    if( fb.width  != px->scr_width ||
923
        fb.height != px->scr_height )
924
    {
925
        px->scr_width  = fb.width;
926
        px->scr_height = fb.height;
927
 
928
        eglDestroyImageKHR(px->dpy, px->screen);
929
 
930
        if(update_fb(px, fb.name, fb.pitch))
931
            return;
932
    };
933
 
934
    update.handle = px->mask.handle;
935
    update.dx     = px->dx;
936
    update.dy     = px->dy;
937
    update.width  = px->width;
938
    update.height = px->height;
939
    update.bo_pitch = (px->width+15) & ~15;
940
    update.bo_map = (int)px->mask.buffer;
941
 
942
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
943
    {
944
        return;
945
    }
946
 
947
    xscale = 1.0/px->scr_width;
948
    yscale = 1.0/px->scr_height;
949
 
950
    r = winx + px->dx + px->width;
951
    b = winy + px->dy + px->height;
952
 
953
    float t0, t1, t2, t5;
954
 
955
//    render->tc_src[1*2]  = 1.0;
956
//    render->tc_src[2*2]  = 1.0;
957
//    render->tc_src[2*2+1]= 1.0;
958
//    render->tc_src[3*2+1]= 1.0;
959
 
960
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
961
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
962
 
963
    vertices[2 * 2] = t2;
964
    vertices[3 * 2] = t0;
965
 
966
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
967
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
968
    vertices[1*2+1] = t1;
969
    vertices[3*2+1] = t5;
970
 
971
    struct shader *shader = &px->shader_y_uv;
972
 
973
    glUseProgram(shader->blit_prog);
974
    glUniform1i(shader->sampler0, 0);
975
    glUniform1i(shader->sampler1, 1);
976
    glUniform1i(shader->sm_mask, 2);
977
 
978
    glActiveTexture(GL_TEXTURE0);
979
    glBindTexture(GL_TEXTURE_2D, planar->tex[0]);
980
 
981
    glActiveTexture(GL_TEXTURE1);
982
    glBindTexture(GL_TEXTURE_2D, planar->tex[1]);
983
 
984
    glActiveTexture(GL_TEXTURE2);
985
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
986
 
987
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
988
 
989
    glFlush();
990
 
991
    return;
992
};
993
 
5371 serge 994
static int hw_create_client(int x, int y, uint32_t width, uint32_t height)
995
{
996
    px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height);
997
 
998
    return !px;
999
};
1000
 
1001
static int hw_resize_client(int x, int y, uint32_t width, uint32_t height)
1002
{
1003
    if( x != px->dx ||
1004
        y != px->dy ||
1005
        width != px->width ||
1006
        height != px->height )
1007
    {
1008
        struct drm_i915_mask_update update;
1009
 
1010
        px->dx     = x;
1011
        px->dy     = y;
1012
        px->width  = width;
1013
        px->height = height;
1014
        update_mask(px);
1015
 
1016
        update.handle = px->mask.handle;
1017
        update.dx     = px->dx;
1018
        update.dy     = px->dy;
1019
        update.width  = px->width;
1020
        update.height = px->height;
1021
        update.bo_pitch = (px->width+15) & ~15;
1022
        update.bo_map = (int)px->mask.buffer;
1023
        update.forced = 1;
1024
 
1025
        drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
1026
    };
1027
 
1028
    return 0;
1029
};
1030
 
1031
static void hw_fini(void)
1032
{
1033
    struct drm_gem_close close;
1034
 
1035
    DBG("%s\n", __FUNCTION__);
1036
 
1037
    eglDestroyImageKHR(px->dpy, px->mask.image);
1038
    user_free(px->mask.buffer);
1039
    close.handle = px->mask.handle;
1040
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
1041
 
1042
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
1043
    glDeleteFramebuffers(1, &px->framebuffer);
1044
    eglDestroyImageKHR(px->dpy, px->screen);
1045
    glDeleteTextures(2, px->texture);
1046
    egl_destroy(px->dpy, px->context);
1047
    free(px);
1048
};
1049
 
1050
static struct pix_driver gl_driver =
1051
{
1052
    HW_TEX_BLIT,
1053
    hw_create_bitmap,
1054
    hw_destroy_bitmap,
1055
    hw_lock_bitmap,
1056
    hw_resize_bitmap,
1057
    hw_blit,
1058
    hw_create_client,
1059
    hw_resize_client,
6115 serge 1060
    hw_fini,
6137 serge 1061
    hw_create_planar,
6142 serge 1062
    hw_destroy_planar,
6137 serge 1063
    hw_blit_planar
5371 serge 1064
};
1065
 
1066
struct pix_driver *DrvInit(uint32_t service)
1067
{
1068
    EGLDisplay     dpy;
1069
    EGLConfig      config;
1070
    EGLContext     context;
1071
    int            ret;
1072
 
1073
    ret = egl_initialize(&dpy, &config, &context);
1074
    if( ret )
1075
        return NULL;
1076
 
1077
    return &gl_driver;
1078
 
1079
err_0:
1080
    egl_destroy(dpy, context);
1081
    return NULL;
1082
}
1083