From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/wm/unique/stret_iteration.c | 209 ++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100755 Source/DirectFB/wm/unique/stret_iteration.c (limited to 'Source/DirectFB/wm/unique/stret_iteration.c') diff --git a/Source/DirectFB/wm/unique/stret_iteration.c b/Source/DirectFB/wm/unique/stret_iteration.c new file mode 100755 index 0000000..30c84e6 --- /dev/null +++ b/Source/DirectFB/wm/unique/stret_iteration.c @@ -0,0 +1,209 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include + +#include + +#include +#include + +D_DEBUG_DOMAIN( UniQuE_StReT, "UniQuE/StReT", "UniQuE's Stack Region Tree" ); + +static inline bool +accept_region( StretRegion *region, int x0, int y0, const DFBRegion *clip ) +{ + if (!D_FLAGS_IS_SET( region->flags, SRF_ACTIVE )) + return false; + + if (!clip) + return true; + + return dfb_region_intersects( clip, DFB_REGION_VALS_TRANSLATED( ®ion->bounds, x0, y0 ) ); +} + +static inline bool +check_depth( int frame ) +{ + if (frame >= STRET_ITERATION_MAX_DEPTH) { + D_WARN( "refusing to exceed depth limit of %d", STRET_ITERATION_MAX_DEPTH ); + return false; + } + + return true; +} + +void +stret_iteration_init( StretIteration *iteration, StretRegion *region, StretRegion *abort_at ) +{ + D_ASSERT( iteration != NULL ); + + D_MAGIC_ASSERT( region, StretRegion ); + D_MAGIC_ASSERT_IF( abort_at, StretRegion ); + + D_DEBUG_AT( UniQuE_StReT, "stret_iteration_init()\n" ); + + iteration->frame = -1; + iteration->x0 = 0; + iteration->y0 = 0; + iteration->abort = abort_at; + + do { + int last_level = region->levels - 1; + int last_child = fusion_vector_size( ®ion->children[last_level] ) - 1; + + iteration->frame++; + + iteration->x0 += region->bounds.x1; + iteration->y0 += region->bounds.y1; + + iteration->stack[iteration->frame].region = region; + iteration->stack[iteration->frame].level = last_level; + iteration->stack[iteration->frame].index = last_child - 1; + + D_DEBUG_AT( UniQuE_StReT, " -> (%d) %p, last level %d, last index %d\n", + iteration->frame, region, last_level, last_child ); + + if (last_child >= 0) { + region = fusion_vector_at( ®ion->children[last_level], last_child ); + + D_MAGIC_ASSERT( region, StretRegion ); + } + } while (fusion_vector_size( ®ion->children[region->levels - 1] ) && check_depth( iteration->frame + 1 )); + + iteration->stack[iteration->frame].index++; + + D_MAGIC_SET( iteration, StretIteration ); +} + +StretRegion * +stret_iteration_next( StretIteration *iteration, + const DFBRegion *clip ) +{ + int index; + int level; + StretRegion *region; + + D_MAGIC_ASSERT( iteration, StretIteration ); + + DFB_REGION_ASSERT_IF( clip ); + + if (clip) + D_DEBUG_AT( UniQuE_StReT, "stret_iteration_next( %d, %d - %dx%d )\n", + DFB_RECTANGLE_VALS_FROM_REGION( clip ) ); + else + D_DEBUG_AT( UniQuE_StReT, "stret_iteration_next()\n" ); + + while (iteration->frame >= 0) { + StretIterationStackFrame *frame = &iteration->stack[iteration->frame]; + + region = frame->region; + level = frame->level; + index = frame->index--; + + D_MAGIC_ASSERT( region, StretRegion ); + + D_DEBUG_AT( UniQuE_StReT, " -> (%d) %p, level [%d/%d], index %d\n", + iteration->frame, region, level, region->levels - 1, index ); + + if (iteration->abort && region == iteration->abort) { + D_MAGIC_CLEAR( iteration ); + return NULL; + } + + if (index < 0) { + level = --frame->level; + + if (level < 0) { + iteration->frame--; + + iteration->x0 -= region->bounds.x1; + iteration->y0 -= region->bounds.y1; + + if (accept_region( region, iteration->x0, iteration->y0, clip )) + return region; + } + else { + frame->index = fusion_vector_size( ®ion->children[level] ) - 1; + } + } + else { + region = fusion_vector_at( ®ion->children[level], index ); + + D_MAGIC_ASSERT( region, StretRegion ); + + if (iteration->abort && region == iteration->abort) { + D_MAGIC_CLEAR( iteration ); + return NULL; + } + + if (accept_region( region, iteration->x0, iteration->y0, clip )) { + level = region->levels - 1; + + while (fusion_vector_is_empty( ®ion->children[level] )) { + if (level) + level--; + else + return region; + } + + if (check_depth( iteration->frame + 1 )) { + frame = &iteration->stack[++iteration->frame]; + + iteration->x0 += region->bounds.x1; + iteration->y0 += region->bounds.y1; + + frame->region = region; + frame->level = level; + frame->index = fusion_vector_size( ®ion->children[level] ) - 1; + + continue; + } + + return region; + } + } + } + + D_ASSUME( iteration->x0 == 0 ); + D_ASSUME( iteration->y0 == 0 ); + + D_MAGIC_CLEAR( iteration ); + + return NULL; +} + +void +stret_iteration_abort( StretIteration *iteration ) +{ + D_MAGIC_CLEAR( iteration ); +} + -- cgit