Subversion Repositories Kolibri OS

Rev

Rev 6137 | Rev 6334 | 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
 
6137 serge 365
    const char *fs_rgba =
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
 
6137 serge 375
    GLuint prog;
376
    GLint  vs_shader, fs_shader;
377
    int ret;
378
 
379
    prog = glCreateProgram();
380
    if(prog == 0)
381
        goto err;
382
 
383
    vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
384
    if(vs_shader == 0)
385
        goto err;
386
 
387
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_rgba);
388
    if(fs_shader == 0)
389
        goto err;
390
 
391
    glAttachShader(prog, vs_shader);
392
    glAttachShader(prog, fs_shader);
393
    glBindAttribLocation(prog, 0, "v_position");
394
    glBindAttribLocation(prog, 1, "v_texcoord0");
395
 
396
    glLinkProgram(prog);
397
    glGetProgramiv(prog, GL_LINK_STATUS, &ret);
398
    if (!ret)
399
    {
400
        GLchar *info;
401
        GLint size;
402
 
403
        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
404
        info = malloc(size);
405
 
406
        glGetProgramInfoLog(prog, size, NULL, info);
407
        DBG("Failed to link: %s\n", info);
408
        DBG("GLSL link failure\n");
409
        free(info);
410
        goto err;
411
    }
412
 
413
    shader->sampler0  = glGetUniformLocation(prog,"tex_rgba");
414
    shader->sm_mask   = glGetUniformLocation(prog,"tex_mask");
415
    shader->blit_prog = prog;
416
    return prog;
417
err:
418
    return 0;
419
}
420
 
421
static GLuint create_y_uv_shader(struct shader *shader)
422
{
423
    const char *vs_src =
424
        "attribute vec4 v_position;\n"
425
        "attribute vec4 v_texcoord0;\n"
426
        "varying vec2 tex_coord;\n"
427
        "void main()\n"
428
        "{\n"
429
        "   gl_Position = v_position;\n"
430
        "   tex_coord   = v_texcoord0.xy;\n"
431
        "}\n";
432
 
433
    const char *fs_y_uv =
434
        "uniform sampler2D tex_src_y;\n"
435
        "uniform sampler2D tex_src_uv;\n"
436
        "uniform sampler2D tex_mask;\n"
437
        "varying vec2 tex_coord;\n"
438
        "void main()\n"
439
        "{\n"
440
        "   float y = 1.16438356 * (texture2D(tex_src_y, tex_coord).x - 0.0625);\n"
441
        "   float u = texture2D(tex_src_uv, tex_coord).r - 0.5;\n"
442
        "   float v = texture2D(tex_src_uv, tex_coord).g - 0.5;\n"
443
        "   gl_FragColor.r = y + 1.59602678 * v;\n"          \
444
        "   gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n" \
445
        "   gl_FragColor.b = y + 2.01723214 * u;\n"          \
446
        "   gl_FragColor.a = texture2D(tex_mask, tex_coord).r;\n"
447
        "}\n";
448
 
449
    GLuint prog;
450
    GLint  vs_shader, fs_shader;
451
    int ret;
452
 
453
    prog = glCreateProgram();
454
    if(prog == 0)
455
        goto err;
456
 
457
    vs_shader = create_shader(GL_VERTEX_SHADER, vs_src);
458
    if(vs_shader == 0)
459
        goto err;
460
 
461
    fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_y_uv);
462
    if(fs_shader == 0)
463
        goto err;
464
 
465
    glAttachShader(prog, vs_shader);
466
    glAttachShader(prog, fs_shader);
467
    glBindAttribLocation(prog, 0, "v_position");
468
    glBindAttribLocation(prog, 1, "v_texcoord0");
469
 
470
    glLinkProgram(prog);
471
    glGetProgramiv(prog, GL_LINK_STATUS, &ret);
472
    if (!ret)
473
    {
474
        GLchar *info;
475
        GLint size;
476
 
477
        glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
478
        info = malloc(size);
479
 
480
        glGetProgramInfoLog(prog, size, NULL, info);
481
        DBG("Failed to link: %s\n", info);
482
        DBG("GLSL link failure\n");
483
        free(info);
484
        goto err;
485
    }
486
 
487
    shader->sampler0  = glGetUniformLocation(prog,"tex_src_y");
488
    shader->sampler1  = glGetUniformLocation(prog,"tex_src_uv");
489
    shader->sm_mask   = glGetUniformLocation(prog,"tex_mask");
490
    shader->blit_prog = prog;
491
    return prog;
492
err:
493
    return 0;
494
}
495
 
496
static struct render* create_render(EGLDisplay dpy, EGLContext context, int dx, int dy, int w, int h)
497
{
498
 
5371 serge 499
    struct drm_i915_fb_info fb;
500
    struct render *px;
6137 serge 501
 
5371 serge 502
    int    ret;
503
 
504
    px = (struct render*)malloc(sizeof(struct render));
505
    if(px == NULL)
506
        goto err_0;
507
 
508
    px->fd  = get_service("DISPLAY");
509
 
510
    __builtin_memset(&fb, 0, sizeof(fb));
511
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
512
    {   DBG("failed to get framebuffer info\n");
513
        goto err_1;
514
    };
515
 
516
    px->dpy     = dpy;
517
    px->context = context;
518
    px->dx      = dx;
519
    px->dy      = dy;
520
    px->width   = w;
521
    px->height  = h;
522
    px->scr_width  = fb.width;
523
    px->scr_height = fb.height;
524
 
525
    glGenTextures(2, px->texture);
526
    if(glGetError() != GL_NO_ERROR)
527
       goto err_1;
528
 
529
    glGenFramebuffers(1, &px->framebuffer);
530
    if(glGetError() != GL_NO_ERROR)
531
       goto err_2;
532
 
533
    glBindFramebuffer(GL_FRAMEBUFFER, px->framebuffer);
534
    if(glGetError() != GL_NO_ERROR)
535
       goto err_3;
536
 
537
    if(update_fb(px, fb.name, fb.pitch))
538
       goto err_4;
539
 
540
    glMatrixMode(GL_PROJECTION);
541
    glLoadIdentity();
542
    glMatrixMode(GL_MODELVIEW);
543
    glLoadIdentity();
544
 
545
    if(create_mask(px))
546
        goto err_4;
547
 
6137 serge 548
    create_y_uv_shader(&px->shader_y_uv);
549
    create_rgba_shader(&px->shader_rgba);
5371 serge 550
 
551
    glEnableClientState(GL_VERTEX_ARRAY);
552
 
553
    glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->vertices);
554
    glEnableVertexAttribArray(0);
555
 
556
    glVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),px->tc_src);
557
    glEnableVertexAttribArray(1);
558
 
559
    glEnable(GL_BLEND);
560
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
561
 
562
    px->tc_src[0]    = 0.0;
563
    px->tc_src[1]    = 0.0;
564
    px->tc_src[1*2]  = 1.0;
565
    px->tc_src[1*2+1]= 0.0;
566
    px->tc_src[2*2]  = 1.0;
567
    px->tc_src[2*2+1]= 1.0;
568
    px->tc_src[3*2]  = 0.0;
569
    px->tc_src[3*2+1]= 1.0;
570
 
571
    DBG("create render framebuffer:%p %dx%d pitch:%d name %d\n",
572
        px->screen,fb.width, fb.height, fb.pitch, fb.name);
573
 
574
    return px;
575
 
576
err_4:
577
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
578
err_3:
579
    glDeleteFramebuffers(1, &px->framebuffer);
580
err_2:
581
    glDeleteTextures(2, px->texture);
582
err_1:
583
    free(px);
584
err_0:
585
    return NULL;
586
};
587
 
588
static struct render *px;
589
 
590
static bitmap_t *hw_create_bitmap(uint32_t width, uint32_t height)
591
{
592
    struct bitmap *bitmap;
593
 
594
    bitmap = malloc(sizeof(struct bitmap));
595
    if(bitmap == NULL)
596
        return NULL;
597
 
598
    glGenTextures(1, &bitmap->tex);
599
    if(glGetError() != GL_NO_ERROR)
600
       goto err_0;
601
 
602
    bitmap->width   = width;
603
    bitmap->height  = height;
604
    bitmap->pitch   = (width*4 + 15) & ~15;
605
 
606
    if(px_create_bitmap(px, bitmap, bitmap->pitch * bitmap->height,
607
                         EGL_DRM_BUFFER_FORMAT_ARGB32_MESA) == 0)
608
    {
609
        return bitmap;
610
    };
611
 
612
    glDeleteTextures(1, &bitmap->tex);
613
err_0:
614
    free(bitmap);
615
    return NULL;
616
};
617
 
6142 serge 618
static int hw_destroy_planar(planar_t *planar)
619
{
620
    glDeleteTextures(planar->num_planes, &planar->tex[0]);
621
 
622
    if(planar->image[2] != NULL)
623
        eglDestroyImageKHR(px->dpy, planar->image[2]);
624
    if(planar->image[1] != NULL)
625
        eglDestroyImageKHR(px->dpy, planar->image[1]);
626
    if(planar->image[0] != NULL)
627
        eglDestroyImageKHR(px->dpy, planar->image[0]);
628
    if(planar->planar_image != NULL)
629
        eglDestroyImageKHR(px->dpy, planar->planar_image);
630
    free(planar);
631
    return 0;
632
};
633
 
6115 serge 634
static planar_t* hw_create_planar(EGLint name, EGLint format, uint32_t width, uint32_t height,
635
                            uint32_t offset0, uint32_t pitch0,
636
                            uint32_t offset1, uint32_t pitch1,
637
                            uint32_t offset2, uint32_t pitch2)
638
{
639
    struct drm_gem_close close;
640
    planar_t *planar;
641
    EGLImageKHR img;
642
    int num_planes;
643
    int i;
644
 
645
    EGLint attribs[] = {
646
        EGL_WIDTH, width,
647
        EGL_HEIGHT,height,
648
        EGL_DRM_BUFFER_FORMAT_MESA, format,
649
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
650
        EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch0,
651
        EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
652
        EGL_DMA_BUF_PLANE1_PITCH_EXT, pitch1,
653
        EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
654
        EGL_DMA_BUF_PLANE2_PITCH_EXT, pitch2,
655
        EGL_NONE, EGL_NONE
656
    };
657
 
658
    switch (format)
659
    {
6137 serge 660
        case WL_DRM_FORMAT_NV12:
6115 serge 661
            num_planes = 2;
662
            break;
663
        case EGL_TEXTURE_Y_U_V_WL:
664
            num_planes = 3;
665
            break;
666
        case EGL_TEXTURE_Y_XUXV_WL:
667
            num_planes = 2;
668
            break;
669
        default:
670
            num_planes = 0;
671
    }
672
 
6137 serge 673
//    printf("%s num_planes %d\n", __FUNCTION__, num_planes);
674
 
6115 serge 675
    if(num_planes == 0)
6137 serge 676
        goto fail;
6115 serge 677
 
678
    planar = calloc(1, sizeof(struct planar));
679
    if(planar == NULL)
6137 serge 680
        goto fail;
6115 serge 681
 
682
    img = eglCreatePlanarImage(px->dpy, px->context, (EGLClientBuffer)name, attribs);
683
    if(img == NULL)
684
        goto err_0;
685
 
686
    planar->width  = width;
687
    planar->height = height;
688
    planar->name   = name;
6142 serge 689
    planar->num_planes = num_planes;
6115 serge 690
    planar->planar_image = img;
691
 
692
    planar->offset[0] = offset0;
693
    planar->offset[1] = offset1;
694
    planar->offset[2] = offset2;
695
 
696
    planar->pitch[0] = pitch0;
697
    planar->pitch[1] = pitch1;
698
    planar->pitch[2] = pitch2;
699
 
700
    glGenTextures(num_planes, &planar->tex[0]);
6142 serge 701
    if(glGetError() != GL_NO_ERROR)
702
       goto err_0;
6115 serge 703
 
704
    for(i = 0; i < num_planes; i++)
705
    {
6137 serge 706
        EGLImageKHR image;
6115 serge 707
        EGLint attr[3];
708
        attr[0] = EGL_WAYLAND_PLANE_WL;
709
        attr[1] = i;
710
        attr[2] = EGL_NONE;
711
 
6137 serge 712
        image = eglCreateImageKHR(px->dpy, px->context,
713
                                   EGL_WAYLAND_BUFFER_WL,(EGLClientBuffer)img, attr);
6142 serge 714
        if(image == NULL)
715
            goto err_1;
6115 serge 716
 
6137 serge 717
        planar->image[i] = image;
6115 serge 718
        glBindTexture(GL_TEXTURE_2D, planar->tex[i]);
6137 serge 719
        if(glGetError() != GL_NO_ERROR)
720
        {
6142 serge 721
            goto err_1;
6137 serge 722
        };
6115 serge 723
 
6137 serge 724
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
725
        if(glGetError() != GL_NO_ERROR)
726
        {
6142 serge 727
            goto err_1;
6137 serge 728
        }
729
 
6115 serge 730
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
731
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
732
    };
733
 
734
    return planar;
735
 
6142 serge 736
err_1:
737
    hw_destroy_planar(planar);
738
    return NULL;
739
 
6115 serge 740
err_0:
741
    free(planar);
6137 serge 742
fail:
6115 serge 743
    return NULL;
744
}
745
 
5371 serge 746
static int hw_destroy_bitmap(bitmap_t * bitmap)
747
{
748
    struct drm_gem_close close;
749
 
750
    glDeleteTextures(1, &bitmap->tex);
751
    eglDestroyImageKHR(px->dpy, bitmap->image);
752
    user_free(bitmap->buffer);
753
    close.handle = bitmap->handle;
754
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
755
    free(bitmap);
6142 serge 756
    return 0;
5371 serge 757
};
758
 
759
static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
760
{
761
    *pitch = bitmap->pitch;
762
 
763
    return bitmap->buffer;
764
};
765
 
766
static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
767
{
768
    return 0;
769
}
770
 
771
char proc_info[1024];
772
 
773
static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y,
774
                   uint32_t w, uint32_t h, int src_x, int src_y)
775
{
776
    struct drm_i915_mask_update update;
777
    struct drm_i915_fb_info fb;
778
 
779
    uint32_t winx, winy, winw, winh;
780
    uint8_t  state;
781
    float xscale, yscale;
782
    int r, b;
783
    float *vertices  = px->vertices;
784
 
785
    get_proc_info(proc_info);
786
 
787
    state  = *(uint8_t*)(proc_info+70);
788
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
789
        return;
790
 
791
    winx = *(uint32_t*)(proc_info+34);
792
    winy = *(uint32_t*)(proc_info+38);
793
    winw = *(uint32_t*)(proc_info+42)+1;
794
    winh = *(uint32_t*)(proc_info+46)+1;
795
 
796
    __builtin_memset(&fb, 0, sizeof(fb));
797
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
798
    {
799
        DBG("failed to get framebuffer info\n");
800
        return;
801
    };
802
 
803
    if( fb.width  != px->scr_width ||
804
        fb.height != px->scr_height )
805
    {
806
        px->scr_width  = fb.width;
807
        px->scr_height = fb.height;
808
 
809
        eglDestroyImageKHR(px->dpy, px->screen);
810
 
811
        if(update_fb(px, fb.name, fb.pitch))
812
            return;
813
    };
814
 
815
    update.handle = px->mask.handle;
816
    update.dx     = px->dx;
817
    update.dy     = px->dy;
818
    update.width  = px->width;
819
    update.height = px->height;
820
    update.bo_pitch = (px->width+15) & ~15;
821
    update.bo_map = (int)px->mask.buffer;
822
 
823
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
824
    {
825
        return;
826
    }
827
 
828
    xscale = 1.0/px->scr_width;
829
    yscale = 1.0/px->scr_height;
830
 
831
    r = winx + px->dx + px->width;
832
    b = winy + px->dy + px->height;
833
 
834
    float t0, t1, t2, t5;
835
 
836
//    render->tc_src[1*2]  = 1.0;
837
//    render->tc_src[2*2]  = 1.0;
838
//    render->tc_src[2*2+1]= 1.0;
839
//    render->tc_src[3*2+1]= 1.0;
840
 
841
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
842
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
843
 
844
    vertices[2 * 2] = t2;
845
    vertices[3 * 2] = t0;
846
 
847
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
848
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
849
    vertices[1*2+1] = t1;
850
    vertices[3*2+1] = t5;
851
 
6137 serge 852
    struct shader *shader = &px->shader_rgba;
853
 
854
    glUseProgram(shader->blit_prog);
855
    glUniform1i(shader->sampler0, 0);
856
    glUniform1i(shader->sm_mask, 1);
857
 
5371 serge 858
    glActiveTexture(GL_TEXTURE0);
859
    glBindTexture(GL_TEXTURE_2D, bitmap->tex);
860
 
861
    glActiveTexture(GL_TEXTURE1);
862
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
863
 
864
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
865
 
866
    glFlush();
867
 
868
    return;
869
};
870
 
6137 serge 871
static int hw_blit_planar(planar_t *planar, int dst_x, int dst_y,
872
                   uint32_t w, uint32_t h, int src_x, int src_y)
873
{
874
    struct drm_i915_mask_update update;
875
    struct drm_i915_fb_info fb;
876
 
877
    uint32_t winx, winy, winw, winh;
878
    uint8_t  state;
879
    float xscale, yscale;
880
    int r, b;
881
    float *vertices  = px->vertices;
882
 
883
    get_proc_info(proc_info);
884
 
885
    state  = *(uint8_t*)(proc_info+70);
886
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
887
        return;
888
 
889
    winx = *(uint32_t*)(proc_info+34);
890
    winy = *(uint32_t*)(proc_info+38);
891
    winw = *(uint32_t*)(proc_info+42)+1;
892
    winh = *(uint32_t*)(proc_info+46)+1;
893
 
894
    __builtin_memset(&fb, 0, sizeof(fb));
895
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
896
    {
897
        DBG("failed to get framebuffer info\n");
898
        return;
899
    };
900
 
901
    if( fb.width  != px->scr_width ||
902
        fb.height != px->scr_height )
903
    {
904
        px->scr_width  = fb.width;
905
        px->scr_height = fb.height;
906
 
907
        eglDestroyImageKHR(px->dpy, px->screen);
908
 
909
        if(update_fb(px, fb.name, fb.pitch))
910
            return;
911
    };
912
 
913
    update.handle = px->mask.handle;
914
    update.dx     = px->dx;
915
    update.dy     = px->dy;
916
    update.width  = px->width;
917
    update.height = px->height;
918
    update.bo_pitch = (px->width+15) & ~15;
919
    update.bo_map = (int)px->mask.buffer;
920
 
921
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
922
    {
923
        return;
924
    }
925
 
926
    xscale = 1.0/px->scr_width;
927
    yscale = 1.0/px->scr_height;
928
 
929
    r = winx + px->dx + px->width;
930
    b = winy + px->dy + px->height;
931
 
932
    float t0, t1, t2, t5;
933
 
934
//    render->tc_src[1*2]  = 1.0;
935
//    render->tc_src[2*2]  = 1.0;
936
//    render->tc_src[2*2+1]= 1.0;
937
//    render->tc_src[3*2+1]= 1.0;
938
 
939
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
940
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
941
 
942
    vertices[2 * 2] = t2;
943
    vertices[3 * 2] = t0;
944
 
945
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
946
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
947
    vertices[1*2+1] = t1;
948
    vertices[3*2+1] = t5;
949
 
950
    struct shader *shader = &px->shader_y_uv;
951
 
952
    glUseProgram(shader->blit_prog);
953
    glUniform1i(shader->sampler0, 0);
954
    glUniform1i(shader->sampler1, 1);
955
    glUniform1i(shader->sm_mask, 2);
956
 
957
    glActiveTexture(GL_TEXTURE0);
958
    glBindTexture(GL_TEXTURE_2D, planar->tex[0]);
959
 
960
    glActiveTexture(GL_TEXTURE1);
961
    glBindTexture(GL_TEXTURE_2D, planar->tex[1]);
962
 
963
    glActiveTexture(GL_TEXTURE2);
964
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
965
 
966
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
967
 
968
    glFlush();
969
 
970
    return;
971
};
972
 
5371 serge 973
static int hw_create_client(int x, int y, uint32_t width, uint32_t height)
974
{
975
    px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height);
976
 
977
    return !px;
978
};
979
 
980
static int hw_resize_client(int x, int y, uint32_t width, uint32_t height)
981
{
982
    if( x != px->dx ||
983
        y != px->dy ||
984
        width != px->width ||
985
        height != px->height )
986
    {
987
        struct drm_i915_mask_update update;
988
 
989
        px->dx     = x;
990
        px->dy     = y;
991
        px->width  = width;
992
        px->height = height;
993
        update_mask(px);
994
 
995
        update.handle = px->mask.handle;
996
        update.dx     = px->dx;
997
        update.dy     = px->dy;
998
        update.width  = px->width;
999
        update.height = px->height;
1000
        update.bo_pitch = (px->width+15) & ~15;
1001
        update.bo_map = (int)px->mask.buffer;
1002
        update.forced = 1;
1003
 
1004
        drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
1005
    };
1006
 
1007
    return 0;
1008
};
1009
 
1010
static void hw_fini(void)
1011
{
1012
    struct drm_gem_close close;
1013
 
1014
    DBG("%s\n", __FUNCTION__);
1015
 
1016
    eglDestroyImageKHR(px->dpy, px->mask.image);
1017
    user_free(px->mask.buffer);
1018
    close.handle = px->mask.handle;
1019
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
1020
 
1021
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
1022
    glDeleteFramebuffers(1, &px->framebuffer);
1023
    eglDestroyImageKHR(px->dpy, px->screen);
1024
    glDeleteTextures(2, px->texture);
1025
    egl_destroy(px->dpy, px->context);
1026
    free(px);
1027
};
1028
 
1029
static struct pix_driver gl_driver =
1030
{
1031
    HW_TEX_BLIT,
1032
    hw_create_bitmap,
1033
    hw_destroy_bitmap,
1034
    hw_lock_bitmap,
1035
    hw_resize_bitmap,
1036
    hw_blit,
1037
    hw_create_client,
1038
    hw_resize_client,
6115 serge 1039
    hw_fini,
6137 serge 1040
    hw_create_planar,
6142 serge 1041
    hw_destroy_planar,
6137 serge 1042
    hw_blit_planar
5371 serge 1043
};
1044
 
1045
struct pix_driver *DrvInit(uint32_t service)
1046
{
1047
    EGLDisplay     dpy;
1048
    EGLConfig      config;
1049
    EGLContext     context;
1050
    int            ret;
1051
 
1052
    ret = egl_initialize(&dpy, &config, &context);
1053
    if( ret )
1054
        return NULL;
1055
 
1056
    return &gl_driver;
1057
 
1058
err_0:
1059
    egl_destroy(dpy, context);
1060
    return NULL;
1061
}
1062