binary compatibility of libdirectfb is broken w/ this commit Signed-off-by: André Draszik <andre.dras...@st.com> --- include/directfb.h | 17 +++ proxy/dispatcher/idirectfbsurface_dispatcher.c | 49 ++++++++ proxy/dispatcher/idirectfbsurface_dispatcher.h | 1 + proxy/requestor/idirectfbsurface_requestor.c | 26 ++++ src/core/gfxcard.c | 148 ++++++++++++++---------- src/core/gfxcard.h | 5 + src/display/idirectfbsurface.c | 127 +++++++++++++------- 7 files changed, 268 insertions(+), 105 deletions(-)
diff --git a/include/directfb.h b/include/directfb.h index c08c77d..14bc5ad 100644 --- a/include/directfb.h +++ b/include/directfb.h @@ -4755,6 +4755,23 @@ D_DEFINE_INTERFACE( IDirectFBSurface, IDirectFBSurface *thiz, IDirectFBEventBuffer *buffer ); + + + /** Blitting functions **/ + /* + * Blit a bunch of areas scaled from the source to the destination + * rectangles. + * + * <b>source_rects</b> and <b>dest_rects</b> will be modified! + */ + DFBResult (*BatchStretchBlit) ( + IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rects, + const DFBRectangle *dest_rects, + int num + ); + ) diff --git a/proxy/dispatcher/idirectfbsurface_dispatcher.c b/proxy/dispatcher/idirectfbsurface_dispatcher.c index e90493b..30b417c 100644 --- a/proxy/dispatcher/idirectfbsurface_dispatcher.c +++ b/proxy/dispatcher/idirectfbsurface_dispatcher.c @@ -594,6 +594,21 @@ IDirectFBSurface_Dispatcher_StretchBlit( IDirectFBSurface *thiz, } static DFBResult +IDirectFBSurface_Dispatcher_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rects, + const DFBRectangle *destination_rects, + int num ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Dispatcher) + + if (!source || num < 1 || !source_rects || !destination_rects) + return DFB_INVARG; + + return DFB_UNIMPLEMENTED; +} + +static DFBResult IDirectFBSurface_Dispatcher_TextureTriangles( IDirectFBSurface *thiz, IDirectFBSurface *source, const DFBVertex *vertices, @@ -1173,6 +1188,36 @@ Dispatch_StretchBlit( IDirectFBSurface *thiz, IDirectFBSurface *real, } static DirectResult +Dispatch_BatchStretchBlit( IDirectFBSurface *thiz, IDirectFBSurface *real, + VoodooManager *manager, VoodooRequestMessage *msg ) +{ + DirectResult ret; + VoodooMessageParser parser; + VoodooInstanceID instance; + unsigned int num; + const DFBRectangle *srects; + const DFBRectangle *drects; + void *surface; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Dispatcher) + + VOODOO_PARSER_BEGIN( parser, msg ); + VOODOO_PARSER_GET_ID( parser, instance ); + VOODOO_PARSER_GET_UINT( parser, num ); + VOODOO_PARSER_GET_DATA( parser, srects ); + VOODOO_PARSER_GET_DATA( parser, drects ); + VOODOO_PARSER_END( parser ); + + ret = voodoo_manager_lookup_local( manager, instance, NULL, &surface ); + if (ret) + return ret; + + real->BatchStretchBlit( real, surface, srects, drects, num ); + + return DFB_OK; +} + +static DirectResult Dispatch_TextureTriangles( IDirectFBSurface *thiz, IDirectFBSurface *real, VoodooManager *manager, VoodooRequestMessage *msg ) { @@ -2049,6 +2094,9 @@ Dispatch( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMes case IDIRECTFBSURFACE_METHOD_ID_StretchBlit: return Dispatch_StretchBlit( dispatcher, real, manager, msg ); + case IDIRECTFBSURFACE_METHOD_ID_BatchStretchBlit: + return Dispatch_BatchStretchBlit( dispatcher, real, manager, msg ); + case IDIRECTFBSURFACE_METHOD_ID_TextureTriangles: return Dispatch_TextureTriangles( dispatcher, real, manager, msg ); @@ -2194,6 +2242,7 @@ Construct( IDirectFBSurface *thiz, thiz->TileBlit = IDirectFBSurface_Dispatcher_TileBlit; thiz->BatchBlit = IDirectFBSurface_Dispatcher_BatchBlit; thiz->StretchBlit = IDirectFBSurface_Dispatcher_StretchBlit; + thiz->BatchStretchBlit = IDirectFBSurface_Dispatcher_BatchStretchBlit; thiz->TextureTriangles = IDirectFBSurface_Dispatcher_TextureTriangles; thiz->SetDrawingFlags = IDirectFBSurface_Dispatcher_SetDrawingFlags; diff --git a/proxy/dispatcher/idirectfbsurface_dispatcher.h b/proxy/dispatcher/idirectfbsurface_dispatcher.h index 5b2c7dc..bfd8784 100644 --- a/proxy/dispatcher/idirectfbsurface_dispatcher.h +++ b/proxy/dispatcher/idirectfbsurface_dispatcher.h @@ -89,5 +89,6 @@ #define IDIRECTFBSURFACE_METHOD_ID_BatchBlit2 58 #define IDIRECTFBSURFACE_METHOD_ID_SetRemoteInstance 59 #define IDIRECTFBSURFACE_METHOD_ID_FillTrapezoids 60 +#define IDIRECTFBSURFACE_METHOD_ID_BatchStretchBlit 61 #endif diff --git a/proxy/requestor/idirectfbsurface_requestor.c b/proxy/requestor/idirectfbsurface_requestor.c index a123891..c8126f7 100644 --- a/proxy/requestor/idirectfbsurface_requestor.c +++ b/proxy/requestor/idirectfbsurface_requestor.c @@ -1057,6 +1057,31 @@ IDirectFBSurface_Requestor_StretchBlit( IDirectFBSurface *thiz, } static DFBResult +IDirectFBSurface_Requestor_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rects, + const DFBRectangle *dest_rects, + int num ) +{ + IDirectFBSurface_Requestor_data *source_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Requestor) + + if (!source || !source_rects || !dest_rects || num < 1) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA_FROM( source, source_data, IDirectFBSurface_Requestor ); + + return voodoo_manager_request( data->manager, data->instance, + IDIRECTFBSURFACE_METHOD_ID_BatchStretchBlit, VREQ_QUEUE, NULL, + VMBT_ID, source_data->instance, + VMBT_UINT, num, + VMBT_DATA, num * sizeof(DFBRectangle), source_rects, + VMBT_DATA, num * sizeof(DFBRectangle), dest_rects, + VMBT_NONE ); +} + +static DFBResult IDirectFBSurface_Requestor_TextureTriangles( IDirectFBSurface *thiz, IDirectFBSurface *source, const DFBVertex *vertices, @@ -1884,6 +1909,7 @@ Construct( IDirectFBSurface *thiz, thiz->TileBlit = IDirectFBSurface_Requestor_TileBlit; thiz->BatchBlit = IDirectFBSurface_Requestor_BatchBlit; thiz->StretchBlit = IDirectFBSurface_Requestor_StretchBlit; + thiz->BatchStretchBlit = IDirectFBSurface_Requestor_BatchStretchBlit; thiz->TextureTriangles = IDirectFBSurface_Requestor_TextureTriangles; thiz->SetDrawingFlags = IDirectFBSurface_Requestor_SetDrawingFlags; diff --git a/src/core/gfxcard.c b/src/core/gfxcard.c index 575a367..275ec94 100644 --- a/src/core/gfxcard.c +++ b/src/core/gfxcard.c @@ -2802,10 +2802,11 @@ void dfb_gfxcard_tileblit( DFBRectangle *rect, int dx1, int dy1, int dx2, int dy dfb_state_unlock( state ); } -void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, - CardState *state ) +void dfb_gfxcard_batchstretchblit( DFBRectangle *srects, DFBRectangle *drects, + unsigned int num, CardState *state ) { - bool hw = false; + int i; + bool need_clip, acquired = false; DFBSurfaceBlittingFlags blittingflags = state->blittingflags; dfb_simplify_blittingflags( &blittingflags ); @@ -2813,24 +2814,16 @@ void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, D_ASSERT( card != NULL ); D_ASSERT( card->shared != NULL ); D_MAGIC_ASSERT( state, CardState ); - D_ASSERT( srect != NULL ); - D_ASSERT( drect != NULL ); + D_ASSERT( srects != NULL ); + D_ASSERT( drects != NULL ); + D_ASSERT( num > 0 ); - D_DEBUG_AT( Core_GraphicsOps, "%s( %d,%d - %dx%d -> %d,%d - %dx%d, %p )\n", - __FUNCTION__, DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect), state ); - - if (state->blittingflags & DSBLIT_ROTATE90) { - if (srect->w == drect->h && srect->h == drect->w) { - dfb_gfxcard_blit( srect, drect->x, drect->y, state ); - return; - } - } - else { - if (srect->w == drect->w && srect->h == drect->h) { - dfb_gfxcard_blit( srect, drect->x, drect->y, state ); - return; - } - } + D_DEBUG_AT( Core_GraphicsOps, "%s( %p )\n", __FUNCTION__, state ); + for (i = 0; i < num; ++i) + D_DEBUG_AT( Core_GraphicsOps, + " -> %d,%d - %dx%d -> %d,%d - %dx%d\n", + DFB_RECTANGLE_VALS(&srects[i]), + DFB_RECTANGLE_VALS(&drects[i]) ); /* The state is locked during graphics operations. */ dfb_state_lock( state ); @@ -2838,35 +2831,58 @@ void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, /* Signal beginning of sequence of operations if not already done. */ dfb_state_start_drawing( state, card ); - if (!(state->render_options & DSRO_MATRIX) && - !dfb_clip_blit_precheck( &state->clip, drect->w, drect->h, - drect->x, drect->y )) - { - dfb_state_unlock( state ); - return; - } + need_clip = (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) + && !D_FLAGS_IS_SET( card->caps.clip, DFXL_STRETCHBLIT )); + for (i = 0; i < num; ++i) { + DFBRectangle *srect = &srects[i]; + DFBRectangle *drect = &drects[i]; - if (dfb_gfxcard_state_check( state, DFXL_STRETCHBLIT ) && - dfb_gfxcard_state_acquire( state, DFXL_STRETCHBLIT )) - { - if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) && - !D_FLAGS_IS_SET( card->caps.clip, DFXL_STRETCHBLIT )) + if (!acquired) { + if (!dfb_gfxcard_state_check( state, DFXL_STRETCHBLIT ) + || !dfb_gfxcard_state_acquire( state, DFXL_STRETCHBLIT )) + break; + + acquired = true; + } + + if ((srect->w == drect->w && srect->h == drect->h) + || ((state->blittingflags & DSBLIT_ROTATE90) + && (srect->w == drect->h && srect->h == drect->w))) { + dfb_gfxcard_state_release( state ); + acquired = false; + dfb_gfxcard_blit_locked( srect, drect->x, drect->y, state ); + continue; + } + + if (!(state->render_options & DSRO_MATRIX) && + !dfb_clip_blit_precheck( &state->clip, drect->w, drect->h, + drect->x, drect->y )) + { + continue; + } + + if (need_clip) dfb_clip_stretchblit( &state->clip, srect, drect ); - hw = card->funcs.StretchBlit( card->driver_data, card->device_data, srect, drect ); + if (!card->funcs.StretchBlit( card->driver_data, card->device_data, + srect, drect )) + break; + } + if (acquired) dfb_gfxcard_state_release( state ); - } - if (!hw) { - if (state->render_options & DSRO_MATRIX) { - int x1, y1, x2, y2; + if (i < num) { + if ((state->render_options & DSRO_MATRIX) && + (state->matrix[0] < 0 || state->matrix[1] != 0 || + state->matrix[3] != 0 || state->matrix[4] < 0 || + state->matrix[6] != 0 || state->matrix[7] != 0)) + { + if (gAcquire( state, DFXL_TEXTRIANGLES )) { + for (; i < num; ++i) { + DFBRectangle *srect = &srects[i]; + DFBRectangle *drect = &drects[i]; - if (state->matrix[0] < 0 || state->matrix[1] != 0 || - state->matrix[3] != 0 || state->matrix[4] < 0 || - state->matrix[6] != 0 || state->matrix[7] != 0) - { - if (gAcquire( state, DFXL_TEXTRIANGLES )) { GenefxVertexAffine v[4]; v[0].x = drect->x; @@ -2892,31 +2908,33 @@ void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, GenefxVertexAffine_Transform( v, 4, state->matrix, state->affine_matrix ); Genefx_TextureTrianglesAffine( state, v, 4, DTTF_FAN, &state->clip ); - - gRelease( state ); } - - dfb_state_unlock( state ); - return; + gRelease( state ); } + } + else if (gAcquire( state, DFXL_STRETCHBLIT )) { + for (; i < num; ++i) { + DFBRectangle *srect = &srects[i]; + DFBRectangle *drect = &drects[i]; - x1 = drect->x; y1 = drect->y; - x2 = x1+drect->w; y2 = y1+drect->h; - DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix); - DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix); - drect->x = x1; drect->y = y1; - drect->w = x2-x1; drect->h = y2-y1; + if (state->render_options & DSRO_MATRIX) { + int x1, y1, x2, y2; - if (!dfb_clip_blit_precheck( &state->clip, - drect->w, drect->h, drect->x, drect->y )) { - dfb_state_unlock( state ); - return; + x1 = drect->x; y1 = drect->y; + x2 = x1+drect->w; y2 = y1+drect->h; + DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix); + DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix); + drect->x = x1; drect->y = y1; + drect->w = x2-x1; drect->h = y2-y1; + } + + if (!dfb_clip_blit_precheck( &state->clip, + drect->w, drect->h, drect->x, drect->y )) + continue; + + gStretchBlit( state, srect, drect ); } - } - if (gAcquire( state, DFXL_STRETCHBLIT )) { - /* Clipping is performed in the following function. */ - gStretchBlit( state, srect, drect ); gRelease( state ); } } @@ -2924,6 +2942,14 @@ void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, dfb_state_unlock( state ); } +void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, + CardState *state ) +{ + D_ONCE ("dfb_gfxcard_batchstretchblit() should be used!"); + + dfb_gfxcard_batchstretchblit( srect, drect, 1, state); +} + void dfb_gfxcard_texture_triangles( DFBVertex *vertices, int num, DFBTriangleFormation formation, CardState *state ) diff --git a/src/core/gfxcard.h b/src/core/gfxcard.h index 1cb391d..a1a661b 100644 --- a/src/core/gfxcard.h +++ b/src/core/gfxcard.h @@ -429,6 +429,11 @@ void dfb_gfxcard_stretchblit ( DFBRectangle *srect, DFBRectangle *drect, CardState *state ); +void dfb_gfxcard_batchstretchblit ( DFBRectangle *srects, + DFBRectangle *drects, + unsigned int num, + CardState *state ); + void dfb_gfxcard_texture_triangles ( DFBVertex *vertices, int num, DFBTriangleFormation formation, diff --git a/src/display/idirectfbsurface.c b/src/display/idirectfbsurface.c index 77fb801..eaf9845 100644 --- a/src/display/idirectfbsurface.c +++ b/src/display/idirectfbsurface.c @@ -2138,17 +2138,19 @@ IDirectFBSurface_BatchBlit2( IDirectFBSurface *thiz, } static DFBResult -IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, - IDirectFBSurface *source, - const DFBRectangle *source_rect, - const DFBRectangle *destination_rect ) -{ - DFBRectangle srect, drect; +IDirectFBSurface_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rects, + const DFBRectangle *dest_rects, + int num ) +{ + int i, dx, dy, sx, sy; + DFBRectangle *srects, *drects; IDirectFBSurface_data *src_data; DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) - D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz ); + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, num ); if (!data->surface) return DFB_DESTROYED; @@ -2160,7 +2162,7 @@ IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, if (data->locked) return DFB_LOCKED; - if (!source) + if (!source || !source_rects || !dest_rects || num < 1) return DFB_INVARG; @@ -2169,53 +2171,59 @@ IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, if (!src_data->area.current.w || !src_data->area.current.h) return DFB_INVAREA; + dx = data->area.wanted.x; + dy = data->area.wanted.y; - /* do destination rectangle */ - if (destination_rect) { - if (destination_rect->w < 1 || destination_rect->h < 1) - return DFB_INVARG; + sx = src_data->area.wanted.x; + sy = src_data->area.wanted.y; - drect = *destination_rect; + srects = alloca( sizeof(DFBRectangle) * num ); + drects = alloca( sizeof(DFBRectangle) * num ); - drect.x += data->area.wanted.x; - drect.y += data->area.wanted.y; - } - else - drect = data->area.wanted; + direct_memcpy( srects, source_rects, sizeof(DFBRectangle) * num ); + direct_memcpy( drects, dest_rects, sizeof(DFBRectangle) * num ); - /* do source rectangle */ - if (source_rect) { - if (source_rect->w < 1 || source_rect->h < 1) - return DFB_INVARG; + for (i=0; i<num; ++i) { + DFBRectangle orig_src; - srect = *source_rect; + if (drects[i].w < 1 || drects[i].h < 1) { + drects[i].w = 0; + drects[i].h = 0; + continue; + } + drects[i].x += dx; + drects[i].y += dy; - srect.x += src_data->area.wanted.x; - srect.y += src_data->area.wanted.y; - } - else - srect = src_data->area.wanted; + if (srects[i].w < 1 || srects[i].h < 1) + return DFB_INVARG; + srects[i].x += sx; + srects[i].y += sy; + /* clipping of the source rectangle must be applied to the destination */ + orig_src = srects[i]; - /* clipping of the source rectangle must be applied to the destination */ - { - DFBRectangle orig_src = srect; + if (!dfb_rectangle_intersect( &srects[i], &src_data->area.current )) { + srects[i].w = srects[i].h = 0; + drects[i].w = drects[i].h = 0; + continue; + } - if (!dfb_rectangle_intersect( &srect, &src_data->area.current )) - return DFB_INVAREA; + if (srects[i].x != orig_src.x) + drects[i].x += (int)( (srects[i].x - orig_src.x) * + (drects[i].w / (float)orig_src.w) + 0.5f); - if (srect.x != orig_src.x) - drect.x += (int)( (srect.x - orig_src.x) * - (drect.w / (float)orig_src.w) + 0.5f); + if (srects[i].y != orig_src.y) + drects[i].y += (int)( (srects[i].y - orig_src.y) * + (drects[i].h / (float)orig_src.h) + 0.5f); - if (srect.y != orig_src.y) - drect.y += (int)( (srect.y - orig_src.y) * - (drect.h / (float)orig_src.h) + 0.5f); + if (srects[i].w != orig_src.w) + drects[i].w = D_ICEIL(drects[i].w * (srects[i].w / (float)orig_src.w)); + if (srects[i].h != orig_src.h) + drects[i].h = D_ICEIL(drects[i].h * (srects[i].h / (float)orig_src.h)); - if (srect.w != orig_src.w) - drect.w = D_ICEIL(drect.w * (srect.w / (float)orig_src.w)); - if (srect.h != orig_src.h) - drect.h = D_ICEIL(drect.h * (srect.h / (float)orig_src.h)); + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d\n", + i, drects[i].x, drects[i].y, drects[i].w, drects[i].h, + srects[i].x, srects[i].y, srects[i].w, srects[i].h ); } dfb_state_set_source( &data->state, src_data->surface ); @@ -2224,11 +2232,41 @@ IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); - CoreGraphicsStateClient_StretchBlit( &data->state_client, &srect, &drect, 1 ); + CoreGraphicsStateClient_StretchBlit( &data->state_client, srects, drects, num ); return DFB_OK; } +static DFBResult +IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + const DFBRectangle *source_rect, + const DFBRectangle *destination_rect ) +{ + DFBRectangle srect, drect; + + if (!source) + return DFB_INVARG; + + if (destination_rect) + drect = *destination_rect; + else { + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + drect = (DFBRectangle) { 0, 0, data->area.wanted.w, data->area.wanted.h }; + } + + if (source_rect) + srect = *source_rect; + else { + IDirectFBSurface_data *sd = (IDirectFBSurface_data*)source->priv; + + srect = (DFBRectangle) { 0, 0, sd->area.wanted.w, sd->area.wanted.h }; + } + + return IDirectFBSurface_BatchStretchBlit( thiz, source, &srect, &drect, 1 ); +} + #define SET_VERTEX(v,X,Y,Z,W,S,T) \ do { \ (v)->x = X; \ @@ -3367,6 +3405,7 @@ DFBResult IDirectFBSurface_Construct( IDirectFBSurface *thiz, thiz->BatchBlit = IDirectFBSurface_BatchBlit; thiz->BatchBlit2 = IDirectFBSurface_BatchBlit2; thiz->StretchBlit = IDirectFBSurface_StretchBlit; + thiz->BatchStretchBlit = IDirectFBSurface_BatchStretchBlit; thiz->TextureTriangles = IDirectFBSurface_TextureTriangles; thiz->SetDrawingFlags = IDirectFBSurface_SetDrawingFlags; -- 1.7.5.4 _______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev