1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 #include <config.h>
30
31 #include <direct/debug.h>
32 #include <direct/mem.h>
33 #include <direct/memcpy.h>
34 #include <direct/messages.h>
35
36 #include <core/core.h>
37 #include <core/graphics_state.h>
38 #include <core/state.h>
39 #include <core/surface.h>
40
41 #include <core/CoreDFB.h>
42 #include <core/CoreGraphicsState.h>
43 #include <core/CoreGraphicsStateClient.h>
44
45 #include <fusion/conf.h>
46
47 D_DEBUG_DOMAIN( Core_GraphicsStateClient, "Core/GfxState/Client", "DirectFB Core Graphics State Client" );
48
49 /**********************************************************************************************************************/
50
51 DFBResult
CoreGraphicsStateClient_Init(CoreGraphicsStateClient * client,CardState * state)52 CoreGraphicsStateClient_Init( CoreGraphicsStateClient *client,
53 CardState *state )
54 {
55 DFBResult ret;
56
57 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p, state %p )\n", __FUNCTION__, client, state );
58
59 D_ASSERT( client != NULL );
60 D_MAGIC_ASSERT( state, CardState );
61 D_MAGIC_ASSERT( state->core, CoreDFB );
62
63 client->core = state->core;
64 client->state = state;
65
66 ret = CoreDFB_CreateState( state->core, &client->gfx_state );
67 if (ret)
68 return ret;
69
70 D_MAGIC_SET( client, CoreGraphicsStateClient );
71
72 return DFB_OK;
73 }
74
75 void
CoreGraphicsStateClient_Deinit(CoreGraphicsStateClient * client)76 CoreGraphicsStateClient_Deinit( CoreGraphicsStateClient *client )
77 {
78 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
79
80 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
81
82 dfb_graphics_state_unref( client->gfx_state );
83
84 D_MAGIC_CLEAR( client );
85 }
86
87 DFBResult
CoreGraphicsStateClient_SetState(CoreGraphicsStateClient * client,CardState * state,StateModificationFlags flags)88 CoreGraphicsStateClient_SetState( CoreGraphicsStateClient *client,
89 CardState *state,
90 StateModificationFlags flags )
91 {
92 DFBResult ret;
93
94 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p, state %p, flags 0x%08x )\n", __FUNCTION__, client, state, flags );
95
96 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
97 D_MAGIC_ASSERT( state, CardState );
98
99 if (flags & SMF_DRAWING_FLAGS) {
100 ret = CoreGraphicsState_SetDrawingFlags( client->gfx_state, state->drawingflags );
101 if (ret)
102 return ret;
103 }
104
105 if (flags & SMF_BLITTING_FLAGS) {
106 ret = CoreGraphicsState_SetBlittingFlags( client->gfx_state, state->blittingflags );
107 if (ret)
108 return ret;
109 }
110
111 if (flags & SMF_CLIP) {
112 ret = CoreGraphicsState_SetClip( client->gfx_state, &state->clip );
113 if (ret)
114 return ret;
115 }
116
117 if (flags & SMF_COLOR) {
118 ret = CoreGraphicsState_SetColor( client->gfx_state, &state->color );
119 if (ret)
120 return ret;
121 }
122
123 if (flags & SMF_SRC_BLEND) {
124 ret = CoreGraphicsState_SetSrcBlend( client->gfx_state, state->src_blend );
125 if (ret)
126 return ret;
127 }
128
129 if (flags & SMF_DST_BLEND) {
130 ret = CoreGraphicsState_SetDstBlend( client->gfx_state, state->dst_blend );
131 if (ret)
132 return ret;
133 }
134
135 if (flags & SMF_SRC_COLORKEY) {
136 ret = CoreGraphicsState_SetSrcColorKey( client->gfx_state, state->src_colorkey );
137 if (ret)
138 return ret;
139 }
140
141 if (flags & SMF_DST_COLORKEY) {
142 ret = CoreGraphicsState_SetDstColorKey( client->gfx_state, state->dst_colorkey );
143 if (ret)
144 return ret;
145 }
146
147 if (flags & SMF_DESTINATION) {
148 D_DEBUG_AT( Core_GraphicsStateClient, " -> DESTINATION %p [%d]\n", state->destination, state->destination->object.id );
149
150 ret = CoreGraphicsState_SetDestination( client->gfx_state, state->destination );
151 if (ret)
152 return ret;
153 }
154
155 if (flags & SMF_SOURCE) {
156 ret = CoreGraphicsState_SetSource( client->gfx_state, state->source );
157 if (ret)
158 return ret;
159 }
160
161 if (flags & SMF_SOURCE_MASK) {
162 ret = CoreGraphicsState_SetSourceMask( client->gfx_state, state->source_mask );
163 if (ret)
164 return ret;
165 }
166
167 if (flags & SMF_SOURCE_MASK_VALS) {
168 ret = CoreGraphicsState_SetSourceMaskVals( client->gfx_state, &state->src_mask_offset, state->src_mask_flags );
169 if (ret)
170 return ret;
171 }
172
173 if (flags & SMF_INDEX_TRANSLATION) {
174 ret = CoreGraphicsState_SetIndexTranslation( client->gfx_state, state->index_translation, state->num_translation );
175 if (ret)
176 return ret;
177 }
178
179 if (flags & SMF_COLORKEY) {
180 ret = CoreGraphicsState_SetColorKey( client->gfx_state, &state->colorkey );
181 if (ret)
182 return ret;
183 }
184
185 if (flags & SMF_RENDER_OPTIONS) {
186 ret = CoreGraphicsState_SetRenderOptions( client->gfx_state, state->render_options );
187 if (ret)
188 return ret;
189 }
190
191 if (flags & SMF_MATRIX) {
192 ret = CoreGraphicsState_SetMatrix( client->gfx_state, state->matrix );
193 if (ret)
194 return ret;
195 }
196
197 if (flags & SMF_SOURCE2) {
198 ret = CoreGraphicsState_SetSource2( client->gfx_state, state->source2 );
199 if (ret)
200 return ret;
201 }
202
203 return DFB_OK;
204 }
205
206 DFBResult
CoreGraphicsStateClient_Update(CoreGraphicsStateClient * client,DFBAccelerationMask accel,CardState * state)207 CoreGraphicsStateClient_Update( CoreGraphicsStateClient *client,
208 DFBAccelerationMask accel,
209 CardState *state )
210 {
211 DFBResult ret;
212 StateModificationFlags flags = SMF_DESTINATION | SMF_CLIP | SMF_RENDER_OPTIONS;
213
214 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
215
216 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
217 D_MAGIC_ASSERT( state, CardState );
218
219 /*
220 * dfb_gfxcard_state_check() moves flags to mod_hw,
221 * called from IDirectFBSurface::GetAccelerationMask().
222 *
223 * FIXME: Add GetAccelerationMask() to CoreGraphicsState flux
224 * and do not load the graphics driver at slaves anymore.
225 */
226 state->modified |= state->mod_hw;
227 state->mod_hw = 0;
228
229 if (state->render_options & DSRO_MATRIX)
230 flags |= SMF_MATRIX;
231
232 if (DFB_DRAWING_FUNCTION( accel )) {
233 flags |= SMF_DRAWING_FLAGS | SMF_COLOR;
234
235 if (state->drawingflags & DSDRAW_BLEND)
236 flags |= SMF_SRC_BLEND | SMF_DST_BLEND;
237
238 if (state->drawingflags & DSDRAW_DST_COLORKEY)
239 flags |= SMF_DST_COLORKEY;
240 }
241 else {
242 flags |= SMF_BLITTING_FLAGS | SMF_SOURCE;
243
244 if (accel == DFXL_BLIT2)
245 flags |= SMF_SOURCE2;
246
247 if (state->blittingflags & (DSBLIT_BLEND_COLORALPHA |
248 DSBLIT_COLORIZE |
249 DSBLIT_SRC_PREMULTCOLOR))
250 flags |= SMF_COLOR;
251
252 if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
253 DSBLIT_BLEND_COLORALPHA))
254 flags |= SMF_SRC_BLEND | SMF_DST_BLEND;
255
256 if (state->blittingflags & DSBLIT_SRC_COLORKEY)
257 flags |= SMF_SRC_COLORKEY;
258
259 if (state->blittingflags & DSBLIT_DST_COLORKEY)
260 flags |= SMF_DST_COLORKEY;
261
262 if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR))
263 flags |= SMF_SOURCE_MASK | SMF_SOURCE_MASK_VALS;
264
265 if (state->blittingflags & DSBLIT_INDEX_TRANSLATION)
266 flags |= SMF_INDEX_TRANSLATION;
267
268 if (state->blittingflags & DSBLIT_COLORKEY_PROTECT)
269 flags |= SMF_COLORKEY;
270 }
271
272 ret = CoreGraphicsStateClient_SetState( client, state, state->modified & flags );
273 if (ret)
274 return ret;
275
276 state->modified &= ~flags;
277
278 return DFB_OK;
279 }
280
281 DFBResult
CoreGraphicsStateClient_DrawRectangles(CoreGraphicsStateClient * client,const DFBRectangle * rects,unsigned int num)282 CoreGraphicsStateClient_DrawRectangles( CoreGraphicsStateClient *client,
283 const DFBRectangle *rects,
284 unsigned int num )
285 {
286 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
287
288 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
289 D_ASSERT( rects != NULL );
290
291 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
292 unsigned int i;
293
294 for (i=0; i<num; i++)
295 // FIXME: will overwrite rects
296 dfb_gfxcard_drawrectangle( (DFBRectangle*) &rects[i], client->state );
297 }
298 else {
299 DFBResult ret;
300
301 CoreGraphicsStateClient_Update( client, DFXL_DRAWRECTANGLE, client->state );
302
303 ret = CoreGraphicsState_DrawRectangles( client->gfx_state, rects, num );
304 if (ret)
305 return ret;
306 }
307
308 return DFB_OK;
309 }
310
311 DFBResult
CoreGraphicsStateClient_DrawLines(CoreGraphicsStateClient * client,const DFBRegion * lines,unsigned int num)312 CoreGraphicsStateClient_DrawLines( CoreGraphicsStateClient *client,
313 const DFBRegion *lines,
314 unsigned int num )
315 {
316 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
317
318 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
319 D_ASSERT( lines != NULL );
320
321 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
322 // FIXME: will overwrite lines
323 dfb_gfxcard_drawlines( (DFBRegion*) lines, num, client->state );
324 }
325 else {
326 DFBResult ret;
327
328 CoreGraphicsStateClient_Update( client, DFXL_DRAWLINE, client->state );
329
330 ret = CoreGraphicsState_DrawLines( client->gfx_state, lines, num );
331 if (ret)
332 return ret;
333 }
334
335 return DFB_OK;
336 }
337
338 DFBResult
CoreGraphicsStateClient_FillRectangles(CoreGraphicsStateClient * client,const DFBRectangle * rects,unsigned int num)339 CoreGraphicsStateClient_FillRectangles( CoreGraphicsStateClient *client,
340 const DFBRectangle *rects,
341 unsigned int num )
342 {
343 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
344
345 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
346 D_ASSERT( rects != NULL );
347
348 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
349 dfb_gfxcard_fillrectangles( rects, num, client->state );
350 }
351 else {
352 DFBResult ret;
353
354 CoreGraphicsStateClient_Update( client, DFXL_FILLRECTANGLE, client->state );
355
356 ret = CoreGraphicsState_FillRectangles( client->gfx_state, rects, num );
357 if (ret)
358 return ret;
359 }
360
361 return DFB_OK;
362 }
363
364 DFBResult
CoreGraphicsStateClient_FillTriangles(CoreGraphicsStateClient * client,const DFBTriangle * triangles,unsigned int num)365 CoreGraphicsStateClient_FillTriangles( CoreGraphicsStateClient *client,
366 const DFBTriangle *triangles,
367 unsigned int num )
368 {
369 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
370
371 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
372 D_ASSERT( triangles != NULL );
373
374 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
375 dfb_gfxcard_filltriangles( triangles, num, client->state );
376 }
377 else {
378 DFBResult ret;
379
380 CoreGraphicsStateClient_Update( client, DFXL_FILLTRIANGLE, client->state );
381
382 ret = CoreGraphicsState_FillTriangles( client->gfx_state, triangles, num );
383 if (ret)
384 return ret;
385 }
386
387 return DFB_OK;
388 }
389
390 DFBResult
CoreGraphicsStateClient_FillTrapezoids(CoreGraphicsStateClient * client,const DFBTrapezoid * trapezoids,unsigned int num)391 CoreGraphicsStateClient_FillTrapezoids( CoreGraphicsStateClient *client,
392 const DFBTrapezoid *trapezoids,
393 unsigned int num )
394 {
395 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
396
397 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
398 D_ASSERT( trapezoids != NULL );
399
400 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
401 dfb_gfxcard_filltrapezoids( trapezoids, num, client->state );
402 }
403 else {
404 DFBResult ret;
405
406 CoreGraphicsStateClient_Update( client, DFXL_FILLTRAPEZOID, client->state );
407
408 ret = CoreGraphicsState_FillTrapezoids( client->gfx_state, trapezoids, num );
409 if (ret)
410 return ret;
411 }
412
413 return DFB_OK;
414 }
415
416 DFBResult
CoreGraphicsStateClient_FillSpans(CoreGraphicsStateClient * client,int y,const DFBSpan * spans,unsigned int num)417 CoreGraphicsStateClient_FillSpans( CoreGraphicsStateClient *client,
418 int y,
419 const DFBSpan *spans,
420 unsigned int num )
421 {
422 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
423
424 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
425 D_ASSERT( spans != NULL );
426
427 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
428 // FIXME: may overwrite spans
429 dfb_gfxcard_fillspans( y, (DFBSpan*) spans, num, client->state );
430 }
431 else {
432 DFBResult ret;
433
434 CoreGraphicsStateClient_Update( client, DFXL_FILLRECTANGLE, client->state );
435
436 ret = CoreGraphicsState_FillSpans( client->gfx_state, y, spans, num );
437 if (ret)
438 return ret;
439 }
440
441 return DFB_OK;
442 }
443
444 DFBResult
CoreGraphicsStateClient_Blit(CoreGraphicsStateClient * client,const DFBRectangle * rects,const DFBPoint * points,unsigned int num)445 CoreGraphicsStateClient_Blit( CoreGraphicsStateClient *client,
446 const DFBRectangle *rects,
447 const DFBPoint *points,
448 unsigned int num )
449 {
450 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
451
452 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
453 D_ASSERT( rects != NULL );
454 D_ASSERT( points != NULL );
455
456 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
457 // FIXME: will overwrite rects, points
458 if (num > 1)
459 dfb_gfxcard_batchblit( (DFBRectangle*) rects, (DFBPoint*) points, num, client->state );
460 else
461 dfb_gfxcard_blit( (DFBRectangle*) rects, ((DFBPoint*)points)->x, ((DFBPoint*)points)->y, client->state );
462 }
463 else {
464 DFBResult ret;
465
466 CoreGraphicsStateClient_Update( client, DFXL_BLIT, client->state );
467
468 ret = CoreGraphicsState_Blit( client->gfx_state, rects, points, num );
469 if (ret)
470 return ret;
471 }
472
473 return DFB_OK;
474 }
475
476 DFBResult
CoreGraphicsStateClient_Blit2(CoreGraphicsStateClient * client,const DFBRectangle * rects,const DFBPoint * points1,const DFBPoint * points2,unsigned int num)477 CoreGraphicsStateClient_Blit2( CoreGraphicsStateClient *client,
478 const DFBRectangle *rects,
479 const DFBPoint *points1,
480 const DFBPoint *points2,
481 unsigned int num )
482 {
483 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
484
485 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
486 D_ASSERT( rects != NULL );
487 D_ASSERT( points1 != NULL );
488 D_ASSERT( points2 != NULL );
489
490 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
491 // FIXME: will overwrite rects, points
492 dfb_gfxcard_batchblit2( (DFBRectangle*) rects, (DFBPoint*) points1, (DFBPoint*) points2, num, client->state );
493 }
494 else {
495 DFBResult ret;
496
497 CoreGraphicsStateClient_Update( client, DFXL_BLIT2, client->state );
498
499 ret = CoreGraphicsState_Blit2( client->gfx_state, rects, points1, points2, num );
500 if (ret)
501 return ret;
502 }
503
504 return DFB_OK;
505 }
506
507 DFBResult
CoreGraphicsStateClient_StretchBlit(CoreGraphicsStateClient * client,const DFBRectangle * srects,const DFBRectangle * drects,unsigned int num)508 CoreGraphicsStateClient_StretchBlit( CoreGraphicsStateClient *client,
509 const DFBRectangle *srects,
510 const DFBRectangle *drects,
511 unsigned int num )
512 {
513 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
514
515 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
516 D_ASSERT( srects != NULL );
517 D_ASSERT( drects != NULL );
518
519 if (num == 0)
520 return DFB_OK;
521
522 if (num != 1)
523 D_UNIMPLEMENTED();
524
525 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
526 // FIXME: will overwrite rects
527 dfb_gfxcard_stretchblit( (DFBRectangle*) srects, (DFBRectangle*) drects, client->state );
528 }
529 else {
530 DFBResult ret;
531
532 CoreGraphicsStateClient_Update( client, DFXL_STRETCHBLIT, client->state );
533
534 ret = CoreGraphicsState_StretchBlit( client->gfx_state, srects, drects, num );
535 if (ret)
536 return ret;
537 }
538
539 return DFB_OK;
540 }
541
542 DFBResult
CoreGraphicsStateClient_TileBlit(CoreGraphicsStateClient * client,const DFBRectangle * rects,const DFBPoint * points1,const DFBPoint * points2,unsigned int num)543 CoreGraphicsStateClient_TileBlit( CoreGraphicsStateClient *client,
544 const DFBRectangle *rects,
545 const DFBPoint *points1,
546 const DFBPoint *points2,
547 unsigned int num )
548 {
549 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
550
551 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
552 D_ASSERT( rects != NULL );
553 D_ASSERT( points1 != NULL );
554 D_ASSERT( points2 != NULL );
555
556 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
557 u32 i;
558
559 // FIXME: will overwrite rects, points
560 for (i=0; i<num; i++)
561 dfb_gfxcard_tileblit( (DFBRectangle*) &rects[i], points1[i].x, points1[i].y, points2[i].x, points2[i].y, client->state );
562 }
563 else {
564 DFBResult ret;
565
566 CoreGraphicsStateClient_Update( client, DFXL_BLIT, client->state );
567
568 ret = CoreGraphicsState_TileBlit( client->gfx_state, rects, points1, points2, num );
569 if (ret)
570 return ret;
571 }
572
573 return DFB_OK;
574 }
575
576 DFBResult
CoreGraphicsStateClient_TextureTriangles(CoreGraphicsStateClient * client,const DFBVertex * vertices,int num,DFBTriangleFormation formation)577 CoreGraphicsStateClient_TextureTriangles( CoreGraphicsStateClient *client,
578 const DFBVertex *vertices,
579 int num,
580 DFBTriangleFormation formation )
581 {
582 D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client );
583
584 D_MAGIC_ASSERT( client, CoreGraphicsStateClient );
585 D_ASSERT( vertices != NULL );
586
587 if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) {
588 // FIXME: may overwrite vertices
589 dfb_gfxcard_texture_triangles( (DFBVertex*) vertices, num, formation, client->state );
590 }
591 else {
592 DFBResult ret;
593
594 CoreGraphicsStateClient_Update( client, DFXL_TEXTRIANGLES, client->state );
595
596 ret = CoreGraphicsState_TextureTriangles( client->gfx_state, vertices, num, formation );
597 if (ret)
598 return ret;
599 }
600
601 return DFB_OK;
602 }
603
604