Hi, attached are some more patches - can they be applied?
- a fix for dfb_gfxcard_drawstring_check_state() - an implementation for IDirectFBSurface::BatchStretchBlit() We have a use case where we have to do loads of stretched blits from src to dst, and the number of stretched rectangles is high enough to cause too high a CPU load using individual StretchBlit() calls. I had sent this patch earlier, and I don't think anybody commented or objected? Cheers, Andre'
>From 6116cc4d11d9791758998b1e300dddc1b184f01e Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Andr=C3=A9=20Draszik?= <andre.dras...@st.com> Date: Mon, 30 Nov 2009 18:08:39 +0000 Subject: [PATCH 1/1] compile warning fix MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Draszik <andre.dras...@st.com> --- src/core/gfxcard.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/core/gfxcard.c b/src/core/gfxcard.c index fcd2cb4..830215c 100644 --- a/src/core/gfxcard.c +++ b/src/core/gfxcard.c @@ -2850,7 +2850,7 @@ bool dfb_gfxcard_drawstring_check_state( CoreFont *font, CardState *state ) if (!data) { D_DEBUG_AT( Core_GfxState, " -> No font data!\n" ); dfb_font_unlock( font ); - return; + return false; } orig_flags = state->blittingflags; -- 1.6.3.3
>From 85b05cda66af62b9afa79bab61346be4940088ad Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Andr=C3=A9=20Draszik?= <andre.dras...@st.com> Date: Sat, 25 Jul 2009 13:41:03 +0100 Subject: [PATCH 1/2] (surface) add some source code level documentation MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Draszik <andre.dras...@st.com> --- src/display/idirectfbsurface.h | 38 ++++++++++++++++++++++++++++++++++++-- 1 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/display/idirectfbsurface.h b/src/display/idirectfbsurface.h index a350054..7c7a0c4 100644 --- a/src/display/idirectfbsurface.h +++ b/src/display/idirectfbsurface.h @@ -50,8 +50,42 @@ typedef struct { DFBSurfaceCapabilities caps; /* capabilities */ struct { - DFBRectangle wanted; /* passed to GetSubSurface */ - DFBRectangle granted; /* clipped by parent on creation */ + /* 'wanted' is passed to GetSubSurface(), it doesn't matter if it's + too large or has negative starting coordinates as long as it + intersects with the 'granted' rectangle of the parent. + 'wanted' should be seen as the origin for operations on that + surface. Non sub surfaces have a 'wanted' rectangle + of '{ 0, 0, width, height }'. 'wanted' is calculated just once + during surface creation. */ + DFBRectangle wanted; + /* 'granted' is the intersection of the 'wanted' rectangle and the + 'granted' one of the parent. If they do not intersect DFB_INVAREA + is returned. For non sub surfaces it's the same as the 'wanted' + rectangle, because it's the rectangle describing the whole + surface. 'granted' is calculated just once during surface + creation */ + DFBRectangle granted; + /* 'current' is the intersection of the 'granted' rectangle and the + surface extents. SetClip() and many other functions are limited + by this. + This way sub surface area information is preserved during surface + resizing, e.g. when resizing a window. Calling SetClip() with NULL + causes the clipping region to exactly cover the 'current' + rectangle, also the flag 'clip_set' is cleared causing the + clipping region to be set to the new 'current' after resizing. If + SetClip() is called with a clipping region specified, an + intersection is done with the 'wanted' rectangle that is then + stored in 'clip_wanted' and 'clip_set' is set. However, if there + is no intersection 'DFB_INVARG' is returned, otherwise another + intersection is made with the 'current' rectangle and gets applied + to the surface's state. + Each resize, after the 'current' rectangle is updated, the + clipping region is set to NULL or 'clip_wanted' depending on + 'clip_set'. This way even clipping regions are restored or + extended automatically. It's now possible to create a fullscreen + primary and call SetVideoMode() with different resolutions or + pixelformats several times without the need for updating the + primary surface by recreating it */ DFBRectangle current; /* currently available area */ DFBInsets insets; /* actually set by the window manager */ } area; -- 1.6.3.3
>From 7418faf296cb3c2a620e580dede2b91ce87cca49 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Andr=C3=A9=20Draszik?= <andre.dras...@st.com> Date: Tue, 4 Aug 2009 01:06:46 +0100 Subject: [PATCH 2/2] (surface) implement IDirectFBSurface::BatchStretchBlit() MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Draszik <andre.dras...@st.com> --- include/directfb.h | 14 +++ proxy/dispatcher/idirectfbsurface_dispatcher.c | 50 ++++++++++ proxy/dispatcher/idirectfbsurface_dispatcher.h | 1 + proxy/requestor/idirectfbsurface_requestor.c | 26 +++++ src/core/gfxcard.c | 80 ++++++++++++++++ src/core/gfxcard.h | 5 + src/display/idirectfbsurface.c | 122 +++++++++++++++++++++--- 7 files changed, 284 insertions(+), 14 deletions(-) diff --git a/include/directfb.h b/include/directfb.h index 12d38ef..0b6c0e1 100644 --- a/include/directfb.h +++ b/include/directfb.h @@ -4150,6 +4150,20 @@ DEFINE_INTERFACE( IDirectFBSurface, const DFBPoint *source2_points, int num ); + + /* + * 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, + DFBRectangle *source_rects, + DFBRectangle *dest_rects, + int num + ); ) diff --git a/proxy/dispatcher/idirectfbsurface_dispatcher.c b/proxy/dispatcher/idirectfbsurface_dispatcher.c index bd58500..b81b1c4 100644 --- a/proxy/dispatcher/idirectfbsurface_dispatcher.c +++ b/proxy/dispatcher/idirectfbsurface_dispatcher.c @@ -579,6 +579,21 @@ IDirectFBSurface_Dispatcher_StretchBlit( IDirectFBSurface *thiz, } static DFBResult +IDirectFBSurface_Dispatcher_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + DFBRectangle *source_rects, + DFBRectangle *destination_rects, + int num ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Dispatcher) + + if (!source) + return DFB_INVARG; + + return DFB_UNIMPLEMENTED; +} + +static DFBResult IDirectFBSurface_Dispatcher_TextureTriangles( IDirectFBSurface *thiz, IDirectFBSurface *source, const DFBVertex *vertices, @@ -1140,6 +1155,37 @@ 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 *source_rects; + const DFBRectangle *dest_rects; + 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, source_rects ); + VOODOO_PARSER_GET_DATA( parser, dest_rects ); + VOODOO_PARSER_END( parser ); + + ret = voodoo_manager_lookup_local( manager, instance, NULL, &surface ); + if (ret) + return ret; + + real->BatchStretchBlit( real, surface, (DFBRectangle *) source_rects, + (DFBRectangle *) dest_rects, num ); + + return DFB_OK; +} + +static DirectResult Dispatch_TextureTriangles( IDirectFBSurface *thiz, IDirectFBSurface *real, VoodooManager *manager, VoodooRequestMessage *msg ) { @@ -1603,6 +1649,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 ); @@ -1733,6 +1782,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 a04b9d8..dcc6eaf 100644 --- a/proxy/dispatcher/idirectfbsurface_dispatcher.h +++ b/proxy/dispatcher/idirectfbsurface_dispatcher.h @@ -87,5 +87,6 @@ #define IDIRECTFBSURFACE_METHOD_ID_Read 56 #define IDIRECTFBSURFACE_METHOD_ID_SetColors 57 #define IDIRECTFBSURFACE_METHOD_ID_BatchBlit2 58 +#define IDIRECTFBSURFACE_METHOD_ID_BatchStretchBlit 59 #endif diff --git a/proxy/requestor/idirectfbsurface_requestor.c b/proxy/requestor/idirectfbsurface_requestor.c index 105f542..a3b5b46 100644 --- a/proxy/requestor/idirectfbsurface_requestor.c +++ b/proxy/requestor/idirectfbsurface_requestor.c @@ -901,6 +901,31 @@ IDirectFBSurface_Requestor_StretchBlit( IDirectFBSurface *thiz, } static DFBResult +IDirectFBSurface_Requestor_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + DFBRectangle *source_rects, + DFBRectangle *dest_rects, + int num ) +{ + IDirectFBSurface_Requestor_data *source_data; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Requestor) + + if (!source) + 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, @@ -1220,6 +1245,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 71f40ce..8ce3996 100644 --- a/src/core/gfxcard.c +++ b/src/core/gfxcard.c @@ -2240,6 +2240,86 @@ void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect, dfb_state_unlock( state ); } +void dfb_gfxcard_batchstretchblit( DFBRectangle *srects, + DFBRectangle *drects, + int num, CardState *state ) +{ + int i = 0; + + D_DEBUG_AT( Core_GraphicsOps, "%s( %p, %p [%d], %p )\n", __FUNCTION__, srects, drects, num, state ); + + D_ASSERT( card != NULL ); + D_ASSERT( card->shared != NULL ); + D_MAGIC_ASSERT( state, CardState ); + D_ASSERT( srects != NULL ); + D_ASSERT( drects != NULL ); + D_ASSERT( num > 0 ); + + /* The state is locked during graphics operations. */ + dfb_state_lock( state ); + + /* Signal beginning of sequence of operations if not already done. */ + dfb_state_start_drawing( state, card ); + + if (dfb_gfxcard_state_check( state, DFXL_STRETCHBLIT ) && + dfb_gfxcard_state_acquire( state, DFXL_STRETCHBLIT )) + { + bool need_clip = (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) + && !D_FLAGS_IS_SET( card->caps.clip, DFXL_STRETCHBLIT )); + + for (; i<num; i++) { + DFBRectangle * __restrict srect = &srects[i]; + DFBRectangle * __restrict drect = &drects[i]; + + if (need_clip) + dfb_clip_stretchblit( &state->clip, srect, drect ); + + if (!card->funcs.StretchBlit( card->driver_data, card->device_data, + srect, drect )) + break; + } + + dfb_gfxcard_state_release( state ); + } + + if (i < num) { + if (gAcquire( state, DFXL_STRETCHBLIT )) { + for (; i<num; i++) { + DFBRectangle * __restrict srect = &srects[i]; + DFBRectangle * __restrict drect = &drects[i]; + + if (state->render_options & DSRO_MATRIX) { + int x1, y1, x2, y2; + + 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) { + D_WARN( "rotation not yet implemented" ); + continue; + } + + 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 ); + } + + gRelease( state ); + } + } + + dfb_state_unlock( 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 535b9b7..3307f07 100644 --- a/src/core/gfxcard.h +++ b/src/core/gfxcard.h @@ -374,6 +374,11 @@ void dfb_gfxcard_stretchblit ( DFBRectangle *srect, DFBRectangle *drect, CardState *state ); +void dfb_gfxcard_batchstretchblit ( DFBRectangle *srects, + DFBRectangle *drects, + 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 c532849..498d322 100644 --- a/src/display/idirectfbsurface.c +++ b/src/display/idirectfbsurface.c @@ -1881,6 +1881,42 @@ IDirectFBSurface_BatchBlit( IDirectFBSurface *thiz, return DFB_OK; } +static bool +clip_StretchBlit( DFBRectangle * __restrict src, + const DFBRectangle * __restrict current_area_src, + DFBRectangle * __restrict dst ) +{ + DFBRectangle orig_src = *src; + + if (!dfb_rectangle_intersect( src, current_area_src )) { + src->w = src->h = 0; + dst->w = dst->h = 0; + return false; + } + + /* clipping of the source rectangle must be applied to the destination */ + + if (src->x != orig_src.x) + dst->x += (int)( (src->x - orig_src.x) * + (dst->w / (float)orig_src.w) + 0.5f); + + if (src->y != orig_src.y) + dst->y += (int)( (src->y - orig_src.y) * + (dst->h / (float)orig_src.h) + 0.5f); + + if (src->w != orig_src.w) + dst->w = D_ICEIL(dst->w * (src->w / (float)orig_src.w)); + + if (src->h != orig_src.h) + dst->h = D_ICEIL(dst->h * (src->h / (float)orig_src.h)); + + D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d\n", + 0, dst->x, dst->y, dst->w, dst->h, + src->x, src->y, src->w, src->h ); + + return true; +} + static DFBResult IDirectFBSurface_BatchBlit2( IDirectFBSurface *thiz, IDirectFBSurface *source, @@ -2055,23 +2091,79 @@ IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, /* clipping of the source rectangle must be applied to the destination */ { - DFBRectangle orig_src = srect; - - if (!dfb_rectangle_intersect( &srect, &src_data->area.current )) + if (!clip_StretchBlit( &srect, &src_data->area.current, &drect )) return DFB_INVAREA; + } + + dfb_state_set_source( &data->state, src_data->surface ); + + /* fetch the source color key from the source if necessary */ + if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) + dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); + + dfb_gfxcard_stretchblit( &srect, &drect, &data->state ); + + return DFB_OK; +} + +static DFBResult +IDirectFBSurface_BatchStretchBlit( IDirectFBSurface *thiz, + IDirectFBSurface *source, + DFBRectangle *source_rects, + DFBRectangle *dest_rects, + int num ) +{ + IDirectFBSurface_data *src_data; + const DFBRectangle *scaled_current_src; + DFBRectangle temp; + int scaled_one; + int i, sx, sy, dx, dy; + bool fixed_point; + + DIRECT_INTERFACE_GET_DATA(IDirectFBSurface) + + D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, num ); + + if (!data->surface) + return DFB_DESTROYED; + + + if (!source || !source_rects || !dest_rects || num < 1) + return DFB_INVARG; + + if (!data->area.current.w || !data->area.current.h) + return DFB_INVAREA; + + if (data->locked) + return DFB_LOCKED; + + + src_data = (IDirectFBSurface_data*)source->priv; - if (srect.x != orig_src.x) - drect.x += (int)( (srect.x - orig_src.x) * - (drect.w / (float)orig_src.w) + 0.5f); + if (!src_data->area.current.w || !src_data->area.current.h) + return DFB_INVAREA; - if (srect.y != orig_src.y) - drect.y += (int)( (srect.y - orig_src.y) * - (drect.h / (float)orig_src.h) + 0.5f); - 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)); + for (i=0; i<num; i++) { + DFBRectangle * __restrict src = &source_rects[i]; + DFBRectangle * __restrict dst = &dest_rects[i]; + + if (dst->w < 1 || dst->h < 1) { + dst->w = 0; + dst->h = 0; + continue; + } + + if (src->w < 1 || src->h < 1) + return DFB_INVARG; + + src->x += src_data->area.wanted.x; + src->y += src_data->area.wanted.y; + + dst->x += data->area.wanted.x; + dst->y += data->area.wanted.y; + + clip_StretchBlit( src, &src_data->area.current, dst ); } dfb_state_set_source( &data->state, src_data->surface ); @@ -2080,7 +2172,8 @@ IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz, if (data->state.blittingflags & DSBLIT_SRC_COLORKEY) dfb_state_set_src_colorkey( &data->state, src_data->src_key.value ); - dfb_gfxcard_stretchblit( &srect, &drect, &data->state ); + dfb_gfxcard_batchstretchblit( source_rects, dest_rects, num, + &data->state ); return DFB_OK; } @@ -2834,6 +2927,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.6.3.3
_______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev