1 /*
2 TI Davinci driver - Graphics Layer
3
4 (c) Copyright 2007 Telio AG
5
6 Written by Denis Oliver Kropp <dok@directfb.org>
7
8 Code is derived from VMWare driver.
9
10 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
11 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
12
13 All rights reserved.
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2 of the License, or (at your option) any later version.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the
27 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA.
29 */
30
31 //#define DIRECT_ENABLE_DEBUG
32
33 #include <config.h>
34
35 #include <asm/types.h>
36
37 #include <stdio.h>
38 #include <sys/ioctl.h>
39
40 #include <directfb.h>
41 #include <directfb_util.h>
42
43 #include <core/layers.h>
44 #include <core/surface.h>
45 #include <core/surface_buffer.h>
46
47 #include <gfx/convert.h>
48
49 #include <direct/memcpy.h>
50 #include <direct/messages.h>
51
52 #include "davincifb.h"
53
54 #include "davinci_gfxdriver.h"
55 #include "davinci_osd.h"
56
57
58 #define D_OSDERROR(x...) do {} while (0)
59
60
61 D_DEBUG_DOMAIN( Davinci_OSD, "Davinci/OSD", "TI Davinci OSD" );
62
63 /**********************************************************************************************************************/
64
65 static int
osdLayerDataSize(void)66 osdLayerDataSize( void )
67 {
68 return sizeof(DavinciOSDLayerData);
69 }
70
71 static DFBResult
osdInitLayer(CoreLayer * layer,void * driver_data,void * layer_data,DFBDisplayLayerDescription * description,DFBDisplayLayerConfig * config,DFBColorAdjustment * adjustment)72 osdInitLayer( CoreLayer *layer,
73 void *driver_data,
74 void *layer_data,
75 DFBDisplayLayerDescription *description,
76 DFBDisplayLayerConfig *config,
77 DFBColorAdjustment *adjustment )
78 {
79 int ret;
80 DavinciDriverData *ddrv = driver_data;
81 DavinciOSDLayerData *dosd = layer_data;
82
83 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
84
85 ret = ioctl( ddrv->fb[OSD0].fd, FBIOGET_VSCREENINFO, &dosd->var0 );
86 if (ret) {
87 D_PERROR( "Davinci/OSD: FBIOGET_VSCREENINFO (fb%d) failed!\n", OSD0 );
88 return DFB_INIT;
89 }
90
91 ret = ioctl( ddrv->fb[OSD1].fd, FBIOGET_VSCREENINFO, &dosd->var1 );
92 if (ret) {
93 D_PERROR( "Davinci/OSD: FBIOGET_VSCREENINFO (fb%d) failed!\n", OSD1 );
94 return DFB_INIT;
95 }
96
97 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
98 if (ret)
99 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 );
100
101 ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
102 if (ret)
103 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 );
104
105 /* set capabilities and type */
106 description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY | DLCAPS_SCREEN_POSITION |
107 DLCAPS_SRC_COLORKEY;
108 description->type = DLTF_GRAPHICS;
109
110 /* set name */
111 snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "TI Davinci OSD" );
112
113 /* fill out the default configuration */
114 config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
115 DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
116 config->width = 640;
117 config->height = 480;
118 config->pixelformat = DSPF_RGB16;
119 config->buffermode = DLBM_FRONTONLY;
120 config->options = DLOP_ALPHACHANNEL;
121
122 return DFB_OK;
123 }
124
125 static DFBResult
osdTestRegion(CoreLayer * layer,void * driver_data,void * layer_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags * failed)126 osdTestRegion( CoreLayer *layer,
127 void *driver_data,
128 void *layer_data,
129 CoreLayerRegionConfig *config,
130 CoreLayerRegionConfigFlags *failed )
131 {
132 CoreLayerRegionConfigFlags fail = 0;
133
134 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
135
136 if (config->options & ~DAVINCI_OSD_SUPPORTED_OPTIONS)
137 fail |= CLRCF_OPTIONS;
138
139 switch (config->format) {
140 case DSPF_RGB444:
141 case DSPF_RGB555:
142 case DSPF_RGB16:
143 case DSPF_RGB32:
144 case DSPF_ARGB4444:
145 case DSPF_ARGB1555:
146 case DSPF_ARGB:
147 break;
148
149 default:
150 fail |= CLRCF_FORMAT;
151 }
152
153 if (config->width < 8 || config->width > 1920)
154 fail |= CLRCF_WIDTH;
155
156 if (config->height < 8 || config->height > 1080)
157 fail |= CLRCF_HEIGHT;
158
159 if (config->dest.x < 0 || config->dest.y < 0)
160 fail |= CLRCF_DEST;
161
162 if (config->dest.x + config->dest.w > 1920)
163 fail |= CLRCF_DEST;
164
165 if (config->dest.y + config->dest.h > 1080)
166 fail |= CLRCF_DEST;
167
168 if (failed)
169 *failed = fail;
170
171 if (fail)
172 return DFB_UNSUPPORTED;
173
174 return DFB_OK;
175 }
176
177 static DFBResult
osdSetRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags updated,CoreSurface * surface,CorePalette * palette,CoreSurfaceBufferLock * lock)178 osdSetRegion( CoreLayer *layer,
179 void *driver_data,
180 void *layer_data,
181 void *region_data,
182 CoreLayerRegionConfig *config,
183 CoreLayerRegionConfigFlags updated,
184 CoreSurface *surface,
185 CorePalette *palette,
186 CoreSurfaceBufferLock *lock )
187 {
188 int ret;
189 DavinciDriverData *ddrv = driver_data;
190 DavinciDeviceData *ddev = ddrv->ddev;
191 DavinciOSDLayerData *dosd = layer_data;
192
193 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
194
195 D_ASSERT( ddrv != NULL );
196 D_ASSERT( ddev != NULL );
197 D_ASSERT( dosd != NULL );
198
199 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
200 if (ret)
201 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 );
202
203 ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
204 if (ret)
205 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 );
206
207 ioctl( ddrv->fb[OSD0].fd, FBIO_WAITFORVSYNC );
208
209 /* Update blend parameters? */
210 if (updated & (CLRCF_OPTIONS | CLRCF_OPACITY | CLRCF_SRCKEY | CLRCF_FORMAT)) {
211 vpbe_blink_option_t blink = {0};
212 vpbe_bitmap_blend_params_t blend = {0};
213
214 D_DEBUG_AT( Davinci_OSD, " -> %s\n", dfb_pixelformat_name( config->format ) );
215
216 if (config->options & DLOP_SRC_COLORKEY) {
217 blend.enable_colorkeying = 1;
218 blend.colorkey = dfb_color_to_pixel( DSPF_RGB16,
219 config->src_key.r,
220 config->src_key.g,
221 config->src_key.b );
222
223 D_DEBUG_AT( Davinci_OSD, " -> color key 0x%02x (%02x %02x %02x)\n",
224 blend.colorkey, config->src_key.r, config->src_key.g, config->src_key.b );
225 }
226 else if (config->options & DLOP_OPACITY) {
227 blend.bf = config->opacity >> 5;
228
229 D_DEBUG_AT( Davinci_OSD, " -> opacity %d/7\n", blend.bf );
230 }
231 else
232 blend.bf = 7;
233
234 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SET_BITMAP_BLEND_FACTOR, &blend );
235 if (ret)
236 D_PERROR( "Davinci/OSD: FBIO_SET_BITMAP_BLEND_FACTOR (fb%d)!\n", OSD0 );
237
238 if (config->options & DLOP_ALPHACHANNEL)
239 dosd->alpha = DFB_PIXELFORMAT_HAS_ALPHA( config->format );
240 else
241 dosd->alpha = 0;
242
243 D_DEBUG_AT( Davinci_OSD, " -> %salpha channel\n", dosd->alpha ? "" : "no " );
244
245 if (dosd->alpha) {
246 if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, dosd->alpha ))
247 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, dosd->alpha );
248 }
249
250 if (ioctl( ddrv->fb[OSD1].fd, FBIO_SET_BLINK_INTERVAL, &blink ))
251 D_OSDERROR( "Davinci/OSD: FBIO_SET_BLINK_INTERVAL (fb%d - disable)!\n", OSD1 );
252 }
253
254 /* Update size? */
255 if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_BUFFERMODE)) {
256 vpbe_window_position_t win_pos;
257
258 D_DEBUG_AT( Davinci_OSD, " -> %dx%d\n", config->width, config->height );
259
260 /*********************************** Start workaround ***********************************/
261 win_pos.xpos = 0;
262 win_pos.ypos = 0;
263
264 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SETPOS, &win_pos );
265 if (ret)
266 D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD0, win_pos.xpos, win_pos.ypos );
267
268 ret = ioctl( ddrv->fb[OSD1].fd, FBIO_SETPOS, &win_pos );
269 if (ret)
270 D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD1, win_pos.xpos, win_pos.ypos );
271
272 updated |= CLRCF_DEST;
273
274 dosd->var0.yoffset = dosd->var1.yoffset = 0;
275 /*********************************** End workaround ***********************************/
276
277 /* Set width and height. */
278 dosd->var0.xres = config->width;
279 dosd->var0.yres = config->height;
280 dosd->var1.xres = config->width;
281 dosd->var1.yres = config->height;
282
283 dosd->var0.yres_virtual = ddrv->fb[OSD0].size / ddev->fix[OSD0].line_length;
284
285 ret = ioctl( ddrv->fb[OSD0].fd, FBIOPUT_VSCREENINFO, &dosd->var0 );
286 if (ret)
287 D_PERROR( "Davinci/OSD: FBIOPUT_VSCREENINFO (fb%d) failed!\n", OSD0 );
288
289 ret = ioctl( ddrv->fb[OSD1].fd, FBIOPUT_VSCREENINFO, &dosd->var1 );
290 if (ret)
291 D_PERROR( "Davinci/OSD: FBIOPUT_VSCREENINFO (fb%d) failed!\n", OSD1 );
292 }
293
294 /* Update position? */
295 if (updated & CLRCF_DEST) {
296 vpbe_window_position_t win_pos;
297
298 D_DEBUG_AT( Davinci_OSD, " -> %d, %d\n", config->dest.x, config->dest.y );
299
300 /* Set horizontal and vertical offset. */
301 win_pos.xpos = config->dest.x;
302 win_pos.ypos = config->dest.y;
303
304 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SETPOS, &win_pos );
305 if (ret)
306 D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD0, config->dest.x, config->dest.y );
307
308 ret = ioctl( ddrv->fb[OSD1].fd, FBIO_SETPOS, &win_pos );
309 if (ret)
310 D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD1, config->dest.x, config->dest.y );
311 }
312
313 davincifb_pan_display( &ddrv->fb[OSD0], &dosd->var0,
314 (config->format == DSPF_RGB16) ? lock : NULL, DSFLIP_NONE, 0, 0 );
315
316 ret = ioctl( ddrv->fb[OSD0].fd, FBIOGET_FSCREENINFO, &ddev->fix[OSD0] );
317 if (ret)
318 D_PERROR( "Davinci/OSD: FBIOGET_FSCREENINFO (fb%d) failed!\n", OSD0 );
319
320 ret = ioctl( ddrv->fb[OSD1].fd, FBIOGET_FSCREENINFO, &ddev->fix[OSD1] );
321 if (ret)
322 D_PERROR( "Davinci/OSD: FBIOGET_FSCREENINFO (fb%d) failed!\n", OSD1 );
323
324 dosd->enable = true;
325
326 if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, 0 ))
327 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, 0 );
328
329 return DFB_OK;
330 }
331
332 static DFBResult
osdRemoveRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data)333 osdRemoveRegion( CoreLayer *layer,
334 void *driver_data,
335 void *layer_data,
336 void *region_data )
337 {
338 int ret;
339 DavinciDriverData *ddrv = driver_data;
340 DavinciOSDLayerData *dosd = layer_data;
341
342 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
343
344 D_ASSERT( ddrv != NULL );
345
346 ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
347 if (ret)
348 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 );
349
350 ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 );
351 if (ret)
352 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 );
353
354 dosd->enable = false;
355
356 return DFB_OK;
357 }
358
359 static void
update_buffers(DavinciDriverData * ddrv,DavinciDeviceData * ddev,CoreSurface * surface,CoreSurfaceBufferLock * lock,const DFBRegion * update)360 update_buffers( DavinciDriverData *ddrv,
361 DavinciDeviceData *ddev,
362 CoreSurface *surface,
363 CoreSurfaceBufferLock *lock,
364 const DFBRegion *update )
365 {
366 DFBRectangle rect;
367 CoreSurfaceBuffer *buffer;
368
369 D_ASSERT( ddrv != NULL );
370 D_ASSERT( ddev != NULL );
371 D_ASSERT( surface != NULL );
372 D_ASSERT( lock != NULL );
373 DFB_REGION_ASSERT_IF( update );
374
375 buffer = lock->buffer;
376 D_ASSERT( buffer != NULL );
377
378 if (update) {
379 rect = DFB_RECTANGLE_INIT_FROM_REGION( update );
380
381 if (rect.x & 1) {
382 rect.x &= ~1;
383 rect.w++;
384 }
385
386 if (rect.w & 1)
387 rect.w++;
388 }
389 else {
390 rect.x = 0;
391 rect.y = 0;
392 rect.w = surface->config.size.w;
393 rect.h = surface->config.size.h;
394 }
395
396 /* Can we use the DSP? */
397 if (ddrv->c64x_present) {
398 int i;
399 int lines = ddev->fix[OSD0].line_length == ddev->fix[OSD1].line_length ? rect.h : 1;
400 unsigned long rgb = ddev->fix[OSD0].smem_start + rect.x * 2 + rect.y * ddev->fix[OSD0].line_length;
401 unsigned long alpha = ddev->fix[OSD1].smem_start + rect.x / 2 + rect.y * ddev->fix[OSD1].line_length;
402 unsigned long src = lock->phys + rect.x * 4 + rect.y * lock->pitch;
403
404 //D_ASSUME( ddev->fix[OSD0].line_length == ddev->fix[OSD1].line_length );
405
406 dfb_gfxcard_lock( GDLF_NONE );
407
408 /* Dither ARGB to RGB16+A3 using the DSP. */
409 for (i=0; i<rect.h; i+=lines) {
410 if (lines > rect.h - i)
411 lines = rect.h - i;
412
413 davinci_c64x_dither_argb__L( &ddrv->tasks, rgb, alpha,
414 ddev->fix[OSD0].line_length, src, lock->pitch, rect.w, lines );
415
416 if (ddev->fix[OSD0].line_length != ddev->fix[OSD1].line_length && lines > 1) {
417 davinci_c64x_blit_32__L( &ddrv->tasks,
418 alpha + ddev->fix[OSD1].line_length, ddev->fix[OSD1].line_length,
419 alpha + ddev->fix[OSD0].line_length, ddev->fix[OSD0].line_length,
420 rect.w/2, lines - 1 );
421 }
422
423 rgb += lines * ddev->fix[OSD0].line_length;
424 alpha += lines * ddev->fix[OSD1].line_length;
425 src += lines * lock->pitch;
426 }
427
428 /* Flush the write cache. */
429 davinci_c64x_write_back_all( &ddrv->c64x );
430
431
432 davinci_c64x_emit_tasks( &ddrv->c64x, &ddrv->tasks, C64X_TEF_RESET );
433
434
435 dfb_gfxcard_unlock();
436 }
437 else {
438 u32 *src32 = lock->addr + rect.y * lock->pitch + DFB_BYTES_PER_LINE( buffer->format, rect.x );
439 int sp4 = lock->pitch / 4;
440 u32 *dst32 = ddrv->fb[OSD0].mem + rect.y * ddev->fix[OSD0].line_length + rect.x * 2;
441 int dp4 = ddev->fix[OSD0].line_length / 4;
442 u8 *dst8 = ddrv->fb[OSD1].mem + rect.y * ddev->fix[OSD1].line_length + rect.x / 2;
443 int dp = ddev->fix[OSD1].line_length;
444 int w2 = rect.w / 2;
445 u32 z = 0;
446
447 switch (buffer->format) {
448 case DSPF_ARGB4444:
449 while (rect.h--) {
450 int x;
451
452 for (x=0; x<w2; x++) {
453 dst32[x] = ((src32[x] & 0x0f000f00) << 4) | ((src32[x] & 0x08000800) ) |
454 ((src32[x] & 0x00f000f0) << 3) | ((src32[x] & 0x00c000c0) >> 1) |
455 ((src32[x] & 0x000f000f) << 1) | ((src32[x] & 0x00080008) >> 3);
456
457 dst8[x] = ((src32[x] & 0xe0000000) >> 29) | ((src32[x] & 0x0000e000) >> 9);
458 }
459
460 src32 += sp4;
461 dst32 += dp4;
462 dst8 += dp;
463 }
464 break;
465
466 case DSPF_ARGB1555:
467 while (rect.h--) {
468 int x;
469
470 for (x=0; x<w2; x++) {
471 dst32[x] = ((src32[x] & 0x7c007c00) << 1) |
472 ((src32[x] & 0x03e003e0) << 1) |
473 (src32[x] & 0x003f003f);
474
475 dst8[x] = ((src32[x] & 0x80000000) ? 0x70 : 0x00) |
476 ((src32[x] & 0x00008000) ? 0x07 : 0x00);
477 }
478
479 src32 += sp4;
480 dst32 += dp4;
481 dst8 += dp;
482 }
483 break;
484
485 case DSPF_ARGB:
486 while (rect.h--) {
487 int x;
488
489 for (x=0; x<w2; x++) {
490 register u32 s0 = src32[(x<<1)+0];
491 register u32 s1 = src32[(x<<1)+1];
492
493 dst32[x] = ((s0 & 0x00f80000) >> 8) |
494 ((s0 & 0x0000fc00) >> 5) |
495 ((s0 & 0x000000f8) >> 3) |
496 ((s1 & 0x00f80000) << 8) |
497 ((s1 & 0x0000fc00) << 11) |
498 ((s1 & 0x000000f8) << 13) ;
499
500 #ifndef DAVINCI_NO_DITHER
501 if ((s0 & s1) >> 24 == 0xff)
502 dst8[x] = 0x77;
503 else {
504 register int pt, da;
505
506 z ^= ((z << 13) | (z >> 19));
507 z += 0x87654321;
508 pt = s0 - ((s0 & 0xf8000000) >> 3);
509 da = (((pt >> 29) & 0x07) + ( ((z&0x1f) - ((pt >> 24) & 0x1f))>>31 )) << 4;
510
511 z ^= ((z << 13) | (z >> 19));
512 z += 0x87654321;
513 pt = s1 - ((s1 & 0xf8000000) >> 3);
514 da |= (((pt >> 29) & 0x07) + ( ((z&0x1f) - ((pt >> 24) & 0x1f))>>31 ));
515
516
517 dst8[x] = da;
518 }
519 #else
520 dst8[x] = ((s0 & 0xe0000000) >> 25) |
521 ((s1 & 0xe0000000) >> 29) ;
522 #endif
523 }
524
525 src32 += sp4;
526 dst32 += dp4;
527 dst8 += dp;
528 }
529 break;
530
531 default:
532 D_ONCE( "unsupported format" );
533 }
534 }
535 }
536
537 static void
update_rgb(DavinciDriverData * ddrv,DavinciDeviceData * ddev,CoreSurface * surface,CoreSurfaceBufferLock * lock,const DFBRegion * update)538 update_rgb( DavinciDriverData *ddrv,
539 DavinciDeviceData *ddev,
540 CoreSurface *surface,
541 CoreSurfaceBufferLock *lock,
542 const DFBRegion *update )
543 {
544 DFBRectangle rect;
545 CoreSurfaceBuffer *buffer;
546
547 D_ASSERT( ddrv != NULL );
548 D_ASSERT( ddev != NULL );
549 D_ASSERT( surface != NULL );
550 D_ASSERT( lock != NULL );
551 DFB_REGION_ASSERT_IF( update );
552
553 buffer = lock->buffer;
554 D_ASSERT( buffer != NULL );
555
556 if (update)
557 rect = DFB_RECTANGLE_INIT_FROM_REGION( update );
558 else {
559 rect.x = 0;
560 rect.y = 0;
561 rect.w = surface->config.size.w;
562 rect.h = surface->config.size.h;
563 }
564
565 dfb_convert_to_rgb16( buffer->format,
566 lock->addr + rect.y * lock->pitch + DFB_BYTES_PER_LINE( buffer->format, rect.x ),
567 lock->pitch,
568 surface->config.size.h,
569 ddrv->fb[OSD0].mem + rect.y * ddev->fix[OSD0].line_length + rect.x * 2,
570 ddev->fix[OSD0].line_length,
571 rect.w, rect.h );
572 }
573
574 static void
enable_osd(DavinciDriverData * ddrv,DavinciOSDLayerData * dosd)575 enable_osd( DavinciDriverData *ddrv,
576 DavinciOSDLayerData *dosd )
577 {
578 if (!dosd->enable)
579 return;
580
581 ioctl( ddrv->fb[OSD0].fd, FBIO_WAITFORVSYNC );
582
583 if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, dosd->alpha ))
584 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, dosd->alpha );
585
586 if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 1 ))
587 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 1 );
588
589 if (ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, dosd->alpha ))
590 D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, dosd->alpha );
591
592 dosd->enable = false;
593 }
594
595 static DFBResult
osdFlipRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreSurface * surface,DFBSurfaceFlipFlags flags,CoreSurfaceBufferLock * lock)596 osdFlipRegion( CoreLayer *layer,
597 void *driver_data,
598 void *layer_data,
599 void *region_data,
600 CoreSurface *surface,
601 DFBSurfaceFlipFlags flags,
602 CoreSurfaceBufferLock *lock )
603 {
604 CoreSurfaceBuffer *buffer;
605 DavinciDriverData *ddrv = driver_data;
606 DavinciDeviceData *ddev = ddrv->ddev;
607 DavinciOSDLayerData *dosd = layer_data;
608
609 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
610
611 D_ASSERT( surface != NULL );
612 D_ASSERT( lock != NULL );
613 D_ASSERT( ddrv != NULL );
614 D_ASSERT( ddev != NULL );
615
616 buffer = lock->buffer;
617 D_ASSERT( buffer != NULL );
618
619 if (buffer->format != DSPF_RGB16) {
620 if (DFB_PIXELFORMAT_HAS_ALPHA( buffer->format ))
621 update_buffers( ddrv, ddev, surface, lock, NULL );
622 else
623 update_rgb( ddrv, ddev, surface, lock, NULL );
624 }
625 else
626 davincifb_pan_display( &ddrv->fb[OSD0], &dosd->var0, lock, flags, 0, 0 );
627
628 dfb_surface_flip( surface, false );
629
630 enable_osd( ddrv, dosd );
631
632 return DFB_OK;
633 }
634
635 static DFBResult
osdUpdateRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreSurface * surface,const DFBRegion * update,CoreSurfaceBufferLock * lock)636 osdUpdateRegion( CoreLayer *layer,
637 void *driver_data,
638 void *layer_data,
639 void *region_data,
640 CoreSurface *surface,
641 const DFBRegion *update,
642 CoreSurfaceBufferLock *lock )
643 {
644 CoreSurfaceBuffer *buffer;
645 DavinciDriverData *ddrv = driver_data;
646 DavinciDeviceData *ddev = ddrv->ddev;
647 DavinciOSDLayerData *dosd = layer_data;
648
649 D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ );
650
651 D_ASSERT( surface != NULL );
652 D_ASSERT( lock != NULL );
653 D_ASSERT( ddrv != NULL );
654 D_ASSERT( ddev != NULL );
655
656 buffer = lock->buffer;
657 D_ASSERT( buffer != NULL );
658
659 if (buffer->format != DSPF_RGB16) {
660 if (DFB_PIXELFORMAT_HAS_ALPHA( buffer->format ))
661 update_buffers( ddrv, ddev, surface, lock, update );
662 else
663 update_rgb( ddrv, ddev, surface, lock, update );
664 }
665
666 enable_osd( ddrv, dosd );
667
668 return DFB_OK;
669 }
670
671 const DisplayLayerFuncs davinciOSDLayerFuncs = {
672 .LayerDataSize = osdLayerDataSize,
673 .InitLayer = osdInitLayer,
674
675 .TestRegion = osdTestRegion,
676 .SetRegion = osdSetRegion,
677 .RemoveRegion = osdRemoveRegion,
678 .FlipRegion = osdFlipRegion,
679 .UpdateRegion = osdUpdateRegion,
680 };
681
682