Subversion Repositories Kolibri OS

Rev

Rev 6115 | 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
 
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
 
6115 serge 618
static planar_t* hw_create_planar(EGLint name, EGLint format, uint32_t width, uint32_t height,
619
                            uint32_t offset0, uint32_t pitch0,
620
                            uint32_t offset1, uint32_t pitch1,
621
                            uint32_t offset2, uint32_t pitch2)
622
{
623
    struct drm_gem_close close;
624
    planar_t *planar;
625
    EGLImageKHR img;
626
    int num_planes;
627
    int i;
628
 
629
    EGLint attribs[] = {
630
        EGL_WIDTH, width,
631
        EGL_HEIGHT,height,
632
        EGL_DRM_BUFFER_FORMAT_MESA, format,
633
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset0,
634
        EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch0,
635
        EGL_DMA_BUF_PLANE1_OFFSET_EXT, offset1,
636
        EGL_DMA_BUF_PLANE1_PITCH_EXT, pitch1,
637
        EGL_DMA_BUF_PLANE2_OFFSET_EXT, offset2,
638
        EGL_DMA_BUF_PLANE2_PITCH_EXT, pitch2,
639
        EGL_NONE, EGL_NONE
640
    };
641
 
642
    switch (format)
643
    {
6137 serge 644
        case WL_DRM_FORMAT_NV12:
6115 serge 645
            num_planes = 2;
646
            break;
647
        case EGL_TEXTURE_Y_U_V_WL:
648
            num_planes = 3;
649
            break;
650
        case EGL_TEXTURE_Y_XUXV_WL:
651
            num_planes = 2;
652
            break;
653
        default:
654
            num_planes = 0;
655
    }
656
 
6137 serge 657
//    printf("%s num_planes %d\n", __FUNCTION__, num_planes);
658
 
6115 serge 659
    if(num_planes == 0)
6137 serge 660
        goto fail;
6115 serge 661
 
662
    planar = calloc(1, sizeof(struct planar));
663
    if(planar == NULL)
6137 serge 664
        goto fail;
6115 serge 665
 
666
    img = eglCreatePlanarImage(px->dpy, px->context, (EGLClientBuffer)name, attribs);
667
    if(img == NULL)
668
        goto err_0;
669
 
670
    planar->width  = width;
671
    planar->height = height;
672
    planar->name   = name;
673
    planar->planar_image = img;
674
 
675
    planar->offset[0] = offset0;
676
    planar->offset[1] = offset1;
677
    planar->offset[2] = offset2;
678
 
679
    planar->pitch[0] = pitch0;
680
    planar->pitch[1] = pitch1;
681
    planar->pitch[2] = pitch2;
682
 
683
    glGenTextures(num_planes, &planar->tex[0]);
684
 
685
    for(i = 0; i < num_planes; i++)
686
    {
6137 serge 687
        EGLImageKHR image;
6115 serge 688
        EGLint attr[3];
689
        attr[0] = EGL_WAYLAND_PLANE_WL;
690
        attr[1] = i;
691
        attr[2] = EGL_NONE;
692
 
6137 serge 693
        image = eglCreateImageKHR(px->dpy, px->context,
694
                                   EGL_WAYLAND_BUFFER_WL,(EGLClientBuffer)img, attr);
6115 serge 695
 
6137 serge 696
        planar->image[i] = image;
6115 serge 697
        glBindTexture(GL_TEXTURE_2D, planar->tex[i]);
698
 
6137 serge 699
        if(glGetError() != GL_NO_ERROR)
700
        {
701
            goto fail;
702
        };
6115 serge 703
 
6137 serge 704
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
705
        if(glGetError() != GL_NO_ERROR)
706
        {
707
            goto fail;
708
        }
709
 
6115 serge 710
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
711
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
712
    };
713
 
714
    return planar;
715
 
716
err_0:
717
    free(planar);
6137 serge 718
fail:
6115 serge 719
 
720
    return NULL;
721
}
722
 
723
 
5371 serge 724
static int hw_destroy_bitmap(bitmap_t * bitmap)
725
{
726
    struct drm_gem_close close;
727
 
728
    glDeleteTextures(1, &bitmap->tex);
729
    eglDestroyImageKHR(px->dpy, bitmap->image);
730
    user_free(bitmap->buffer);
731
    close.handle = bitmap->handle;
732
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
733
    free(bitmap);
734
};
735
 
736
static void *hw_lock_bitmap(bitmap_t *bitmap, uint32_t *pitch)
737
{
738
    *pitch = bitmap->pitch;
739
 
740
    return bitmap->buffer;
741
};
742
 
743
static int hw_resize_bitmap(bitmap_t * bitmap, uint32_t width, uint32_t height)
744
{
745
    return 0;
746
}
747
 
748
char proc_info[1024];
749
 
750
static int hw_blit(bitmap_t *bitmap, int dst_x, int dst_y,
751
                   uint32_t w, uint32_t h, int src_x, int src_y)
752
{
753
    struct drm_i915_mask_update update;
754
    struct drm_i915_fb_info fb;
755
 
756
    uint32_t winx, winy, winw, winh;
757
    uint8_t  state;
758
    float xscale, yscale;
759
    int r, b;
760
    float *vertices  = px->vertices;
761
 
762
    get_proc_info(proc_info);
763
 
764
    state  = *(uint8_t*)(proc_info+70);
765
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
766
        return;
767
 
768
    winx = *(uint32_t*)(proc_info+34);
769
    winy = *(uint32_t*)(proc_info+38);
770
    winw = *(uint32_t*)(proc_info+42)+1;
771
    winh = *(uint32_t*)(proc_info+46)+1;
772
 
773
    __builtin_memset(&fb, 0, sizeof(fb));
774
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
775
    {
776
        DBG("failed to get framebuffer info\n");
777
        return;
778
    };
779
 
780
    if( fb.width  != px->scr_width ||
781
        fb.height != px->scr_height )
782
    {
783
        px->scr_width  = fb.width;
784
        px->scr_height = fb.height;
785
 
786
        eglDestroyImageKHR(px->dpy, px->screen);
787
 
788
        if(update_fb(px, fb.name, fb.pitch))
789
            return;
790
    };
791
 
792
    update.handle = px->mask.handle;
793
    update.dx     = px->dx;
794
    update.dy     = px->dy;
795
    update.width  = px->width;
796
    update.height = px->height;
797
    update.bo_pitch = (px->width+15) & ~15;
798
    update.bo_map = (int)px->mask.buffer;
799
 
800
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
801
    {
802
        return;
803
    }
804
 
805
    xscale = 1.0/px->scr_width;
806
    yscale = 1.0/px->scr_height;
807
 
808
    r = winx + px->dx + px->width;
809
    b = winy + px->dy + px->height;
810
 
811
    float t0, t1, t2, t5;
812
 
813
//    render->tc_src[1*2]  = 1.0;
814
//    render->tc_src[2*2]  = 1.0;
815
//    render->tc_src[2*2+1]= 1.0;
816
//    render->tc_src[3*2+1]= 1.0;
817
 
818
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
819
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
820
 
821
    vertices[2 * 2] = t2;
822
    vertices[3 * 2] = t0;
823
 
824
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
825
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
826
    vertices[1*2+1] = t1;
827
    vertices[3*2+1] = t5;
828
 
6137 serge 829
    struct shader *shader = &px->shader_rgba;
830
 
831
    glUseProgram(shader->blit_prog);
832
    glUniform1i(shader->sampler0, 0);
833
    glUniform1i(shader->sm_mask, 1);
834
 
5371 serge 835
    glActiveTexture(GL_TEXTURE0);
836
    glBindTexture(GL_TEXTURE_2D, bitmap->tex);
837
 
838
    glActiveTexture(GL_TEXTURE1);
839
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
840
 
841
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
842
 
843
    glFlush();
844
 
845
    return;
846
};
847
 
6137 serge 848
static int hw_blit_planar(planar_t *planar, int dst_x, int dst_y,
849
                   uint32_t w, uint32_t h, int src_x, int src_y)
850
{
851
    struct drm_i915_mask_update update;
852
    struct drm_i915_fb_info fb;
853
 
854
    uint32_t winx, winy, winw, winh;
855
    uint8_t  state;
856
    float xscale, yscale;
857
    int r, b;
858
    float *vertices  = px->vertices;
859
 
860
    get_proc_info(proc_info);
861
 
862
    state  = *(uint8_t*)(proc_info+70);
863
    if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
864
        return;
865
 
866
    winx = *(uint32_t*)(proc_info+34);
867
    winy = *(uint32_t*)(proc_info+38);
868
    winw = *(uint32_t*)(proc_info+42)+1;
869
    winh = *(uint32_t*)(proc_info+46)+1;
870
 
871
    __builtin_memset(&fb, 0, sizeof(fb));
872
    if( 0 != drm_ioctl(px->fd, SRV_FBINFO, &fb))
873
    {
874
        DBG("failed to get framebuffer info\n");
875
        return;
876
    };
877
 
878
    if( fb.width  != px->scr_width ||
879
        fb.height != px->scr_height )
880
    {
881
        px->scr_width  = fb.width;
882
        px->scr_height = fb.height;
883
 
884
        eglDestroyImageKHR(px->dpy, px->screen);
885
 
886
        if(update_fb(px, fb.name, fb.pitch))
887
            return;
888
    };
889
 
890
    update.handle = px->mask.handle;
891
    update.dx     = px->dx;
892
    update.dy     = px->dy;
893
    update.width  = px->width;
894
    update.height = px->height;
895
    update.bo_pitch = (px->width+15) & ~15;
896
    update.bo_map = (int)px->mask.buffer;
897
 
898
    if(drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update))
899
    {
900
        return;
901
    }
902
 
903
    xscale = 1.0/px->scr_width;
904
    yscale = 1.0/px->scr_height;
905
 
906
    r = winx + px->dx + px->width;
907
    b = winy + px->dy + px->height;
908
 
909
    float t0, t1, t2, t5;
910
 
911
//    render->tc_src[1*2]  = 1.0;
912
//    render->tc_src[2*2]  = 1.0;
913
//    render->tc_src[2*2+1]= 1.0;
914
//    render->tc_src[3*2+1]= 1.0;
915
 
916
    vertices[0]     = t0 = 2*(winx+px->dx)*xscale - 1.0;
917
    vertices[1 * 2] = t2 = 2*r*xscale - 1.0;
918
 
919
    vertices[2 * 2] = t2;
920
    vertices[3 * 2] = t0;
921
 
922
    vertices[1]     = t1 = 2*(winy+px->dy)*yscale - 1.0;
923
    vertices[2*2+1] = t5 = 2*b*yscale - 1.0;
924
    vertices[1*2+1] = t1;
925
    vertices[3*2+1] = t5;
926
 
927
    struct shader *shader = &px->shader_y_uv;
928
 
929
    glUseProgram(shader->blit_prog);
930
    glUniform1i(shader->sampler0, 0);
931
    glUniform1i(shader->sampler1, 1);
932
    glUniform1i(shader->sm_mask, 2);
933
 
934
    glActiveTexture(GL_TEXTURE0);
935
    glBindTexture(GL_TEXTURE_2D, planar->tex[0]);
936
 
937
    glActiveTexture(GL_TEXTURE1);
938
    glBindTexture(GL_TEXTURE_2D, planar->tex[1]);
939
 
940
    glActiveTexture(GL_TEXTURE2);
941
    glBindTexture(GL_TEXTURE_2D, px->texture[TEX_MASK]);
942
 
943
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
944
 
945
    glFlush();
946
 
947
    return;
948
};
949
 
5371 serge 950
static int hw_create_client(int x, int y, uint32_t width, uint32_t height)
951
{
952
    px = create_render(eglGetCurrentDisplay(), eglGetCurrentContext(), x, y, width, height);
953
 
954
    return !px;
955
};
956
 
957
static int hw_resize_client(int x, int y, uint32_t width, uint32_t height)
958
{
959
    if( x != px->dx ||
960
        y != px->dy ||
961
        width != px->width ||
962
        height != px->height )
963
    {
964
        struct drm_i915_mask_update update;
965
 
966
        px->dx     = x;
967
        px->dy     = y;
968
        px->width  = width;
969
        px->height = height;
970
        update_mask(px);
971
 
972
        update.handle = px->mask.handle;
973
        update.dx     = px->dx;
974
        update.dy     = px->dy;
975
        update.width  = px->width;
976
        update.height = px->height;
977
        update.bo_pitch = (px->width+15) & ~15;
978
        update.bo_map = (int)px->mask.buffer;
979
        update.forced = 1;
980
 
981
        drm_ioctl(px->fd, SRV_MASK_UPDATE_EX, &update);
982
    };
983
 
984
    return 0;
985
};
986
 
987
static void hw_fini(void)
988
{
989
    struct drm_gem_close close;
990
 
991
    DBG("%s\n", __FUNCTION__);
992
 
993
    eglDestroyImageKHR(px->dpy, px->mask.image);
994
    user_free(px->mask.buffer);
995
    close.handle = px->mask.handle;
996
    drm_ioctl(px->fd, DRM_IOCTL_GEM_CLOSE, &close);
997
 
998
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
999
    glDeleteFramebuffers(1, &px->framebuffer);
1000
    eglDestroyImageKHR(px->dpy, px->screen);
1001
    glDeleteTextures(2, px->texture);
1002
    egl_destroy(px->dpy, px->context);
1003
    free(px);
1004
};
1005
 
1006
static struct pix_driver gl_driver =
1007
{
1008
    HW_TEX_BLIT,
1009
    hw_create_bitmap,
1010
    hw_destroy_bitmap,
1011
    hw_lock_bitmap,
1012
    hw_resize_bitmap,
1013
    hw_blit,
1014
    hw_create_client,
1015
    hw_resize_client,
6115 serge 1016
    hw_fini,
6137 serge 1017
    hw_create_planar,
1018
    hw_blit_planar
5371 serge 1019
};
1020
 
1021
struct pix_driver *DrvInit(uint32_t service)
1022
{
1023
    EGLDisplay     dpy;
1024
    EGLConfig      config;
1025
    EGLContext     context;
1026
    int            ret;
1027
 
1028
    ret = egl_initialize(&dpy, &config, &context);
1029
    if( ret )
1030
        return NULL;
1031
 
1032
    return &gl_driver;
1033
 
1034
err_0:
1035
    egl_destroy(dpy, context);
1036
    return NULL;
1037
}
1038