IntersectGeneralClipRegion and view implementation

2 views
Skip to first unread message

Cecil Wei

unread,
Feb 9, 2010, 7:58:21 PM2/9/10
to google-gadgets-for-linux-user
Hi all,

I was doing the integration of Skia and GGL. and there is one thing
that I don't quite understand about IntersectGeneralClipRegion.

The comment says that the clip region shall be the union of a list of
rectangles, so when we are going to repaint the dirty regions, you
first clear the union of dirty regions.

target = canvas_cache_;
target->PushState();
target->IntersectGeneralClipRegion(clip_region_);
target->ClearRect(0, 0, width_, height_);


However, when element check if it is overlapped with the dirty
regions, the following function is invoked.

bool View::IsElementInClipRegion(const BasicElement *element) const {
return !impl_->clip_region_enabled_ ||
impl_->clip_region_.Overlaps(element->GetExtentsInView());
}

if one element is not overlapped with any of the dirty regions but is
in the union area, it is not repainted.

I am not sure if it is because of the imlementation difference of skia
and cairo, or may be the implementation bug of my adaptation. But it
seems to be a little wierd to me according to the implementation of
view as you clear the whole union region but only repaint those in
dirty regions.

Can someone help to explain this? thank you so much.

James Su

unread,
Feb 9, 2010, 11:20:39 PM2/9/10
to google-gadgets...@googlegroups.com
A clip region is simply a set of clip rectangles, however in order to reduce the number of clip rectangles in a clip region as much as possible, a fuzzy ratio may be set, so that if two or more clip rectangles are overlapped to some extent, they will be merged into a larger clip rectangle (so called union). In most cases, the fuzzy ratio will be 1, which won't do such optimization at all, except if two clip rectangles share one same edge. All of these optimizations are done inside ClipRegion class.

So in a Canvas implementation, a ClipRegion object can be simply treated as a set of clip rectangles. You can use ClipRegion::GetRectangleCount() and ClipRegion::GetRectangle() methods to enumerate all clip rectangles in a clip region. Note that, the area of a clip region (the dirty area) is the total sum of the area covered by all its clip rectangles, rather than the intersection area of all clip rectangles.

Regards
James Su

2010/2/10 Cecil Wei <ceci...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "google-gadgets-for-linux-user" group.
To post to this group, send email to google-gadgets...@googlegroups.com.
To unsubscribe from this group, send email to google-gadgets-for-l...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-gadgets-for-linux-user?hl=en.


Cecil Wei

unread,
Feb 10, 2010, 4:18:26 AM2/10/10
to google-gadgets-for-linux-user
Hi James,

thank you for your response. I think the problem is about the
understanding of the clip region.

According to you, "the area of a clip region (the dirty area) is the
total sum of the area covered by all its clip rectangles".

But look at the definition of IntersectGeneralClipRegion

/**
* Intersect the clipping region with a general region, which is
represented
* by the union of a list of rectangles.
* @param region the general clip region.
* @return @c true on success and @c false otherwise.
*/
virtual bool IntersectGeneralClipRegion(const ClipRegion &region) =
0;

The area could be larger than the sum of all the clip rectangles. For
example, if the clip region contains

(0, 0, 10, 10) and (15, 15, 30, 30)

the union of these 2 clip rectangles will be (0, 0, 30, 30)

so when you do

target->IntersectGeneralClipRegion(clip_region_);
target->ClearRect(0, 0, width_, height_);

the contents in (0, 0, 30, 30) will be cleared. But if you have one
element that is in (11, 11, 14, 14)

it is not repainted because View::IsElementInClipRegion will return
false.

Please correct me if I am wrong. thank you,

James Su

unread,
Feb 10, 2010, 4:41:46 AM2/10/10
to google-gadgets...@googlegroups.com
Ok, the "union" in the comment actually means "sum" or "aggregate", rather than the union you mentioned. We should have a clearer comment here.

Regards
James Su

2010/2/10 Cecil Wei <ceci...@gmail.com>
Hi James,

--

Cecil Wei

unread,
Feb 10, 2010, 4:45:06 AM2/10/10
to google-gadgets-for-linux-user
To avoid misunderstanding, when I say (0, 0, 10, 10) I mean top = 0,
left = 0, bottom = 10, right = 10.

thank you,

James Su

unread,
Feb 10, 2010, 5:17:10 AM2/10/10
to google-gadgets...@googlegroups.com
Yes I understand. For this example, the clip region just consists of those two rectangles. No union operation should be performed.

Regards
James Su

2010/2/10 Cecil Wei <ceci...@gmail.com>
To avoid misunderstanding, when I say (0, 0, 10, 10) I mean top = 0,

left = 0, bottom = 10, right = 10.

thank you,

James Su

unread,
Feb 10, 2010, 5:18:33 AM2/10/10
to google-gadgets...@googlegroups.com
Besides, I'm very interested in your work. It'll be best if your work can be integrated into upstream code.

Regards
James Su

Cecil Wei

unread,
Feb 10, 2010, 10:37:28 AM2/10/10
to google-gadgets-for-linux-user
Dear James,

So the problem I am having now is that most of the clipRect API
provided by graphics framework gives out only one rectangle.

Please have a look at the definition of Skia Canvas's clipRect

/** Modify the current clip with the specified rectangle.
@param rect The rect to intersect with the current clip
@param op The region op to apply to the current clip
@return true if the canvas' clip is non-empty
*/
virtual bool clipRect(const SkRect& rect,
SkRegion::Op op = SkRegion::kIntersect_Op);

or the one defined in Java

public abstract void clipRect(int x,
int y,
int width,
int height)
Intersects the current clip with the specified rectangle. The
resulting clipping area is the intersection of the current clipping
area and the specified rectangle.

So it is not likely that I can clear only the dirty regions without
modifying View::Draw function.

I would think the description about IntersectGeneralClipRegion is
valid. the dirty region shall be the union of dirty rectangles.

But View::IsElementInClipRegion might need to be modified as it only
check if the element is overlapped with any dirty rectangle in the
list.

James Su

unread,
Feb 10, 2010, 10:17:31 PM2/10/10
to google-gadgets...@googlegroups.com


2010/2/10 Cecil Wei <ceci...@gmail.com>

Dear James,

So the problem I am having now is that most of the clipRect API
provided by graphics framework gives out only one rectangle.

Please have a look at the definition of Skia Canvas's clipRect

   /** Modify the current clip with the specified rectangle.
       @param rect The rect to intersect with the current clip
       @param op The region op to apply to the current clip
       @return true if the canvas' clip is non-empty
   */
   virtual bool clipRect(const SkRect& rect,
                         SkRegion::Op op = SkRegion::kIntersect_Op);
Can you write a demo program to check the behavior of kUnion_Op? I guess you may misunderstand it. Otherwise you may try clipRegion(), or setClipRegion(). I believe Skia supports multi-rectangles clip region, just like what cairo supports.
 

or the one defined in Java

public abstract void clipRect(int x,
                             int y,
                             int width,
                             int height)
Intersects the current clip with the specified rectangle. The
resulting clipping area is the intersection of the current clipping
area and the specified rectangle.

So it is not likely that I can clear only the dirty regions without
modifying View::Draw function.

I would think the description about IntersectGeneralClipRegion is
valid. the dirty region shall be the union of dirty rectangles.
No. Multi-rectangles clip region is mandatory for performance. Are you sure your understand "union" correctly?
 

But View::IsElementInClipRegion might need to be modified as it only
check if the element is overlapped with any dirty rectangle in the
list.
Absolutely incorrect.
Reply all
Reply to author
Forward
0 new messages