[haiku-commits] haiku: hrev47230 - in src: servers/app/drawing tests/servers/app/transformation

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 19 May 2014 14:18:57 +0200 (CEST)

hrev47230 adds 3 changesets to branch 'master'
old head: a8f9011015d0a7b00d0fd0772ede3e9fec6347e0
new head: 2f9ac9582db33ca8eb53261f19486abfa98b41c1
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=2f9ac95+%5Ea8f9011

----------------------------------------------------------------------------

66bce82: CID 1210936: use after free.

79eb23a: Fix handling of filled rectangles with transforms.
  
  The DrawingEngine didn't properly make a distinction between the
  rectangle being filled and the damaged region on screen. This led to
  unexpected results when using BAffineTransform.

2f9ac95: Transformation: add one more test
  
  * Add test for a translation that makes things that are out of view
  bounds to become visible
  * Fix the "rectangles" test to handle scrolling of the view. It seems
  that in some cases some of the rectangles are not drawn.
  
  The gradient and bitmap tests currently have problem with view
  scrolling, but I'm not sure why.

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

3 files changed, 86 insertions(+), 36 deletions(-)
src/apps/terminal/TermView.cpp                |  4 +-
src/servers/app/drawing/DrawingEngine.cpp     | 86 ++++++++++++++---------
src/tests/servers/app/transformation/main.cpp | 32 +++++++++

############################################################################

Commit:      66bce8233aa664cfb6ac31fb234a0cf4950e585e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=66bce82
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Fri May 16 07:17:15 2014 UTC

CID 1210936: use after free.

----------------------------------------------------------------------------

diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp
index 8bd3616..f06ab5f 100644
--- a/src/apps/terminal/TermView.cpp
+++ b/src/apps/terminal/TermView.cpp
@@ -2601,10 +2601,10 @@ TermView::_AddHighlight(Highlight* highlight)
 void
 TermView::_RemoveHighlight(Highlight* highlight)
 {
-       fHighlights.RemoveItem(highlight);
-
        if (!highlight->IsEmpty())
                _InvalidateTextRange(highlight->Start(), highlight->End());
+
+       fHighlights.RemoveItem(highlight);
 }
 
 

############################################################################

Commit:      79eb23a82dfd137b0a8f2a70058463f6d7a3b476
URL:         http://cgit.haiku-os.org/haiku/commit/?id=79eb23a
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Mon May 19 11:18:45 2014 UTC

Fix handling of filled rectangles with transforms.

The DrawingEngine didn't properly make a distinction between the
rectangle being filled and the damaged region on screen. This led to
unexpected results when using BAffineTransform.

----------------------------------------------------------------------------

diff --git a/src/servers/app/drawing/DrawingEngine.cpp 
b/src/servers/app/drawing/DrawingEngine.cpp
index e37ad03..a07a255 100644
--- a/src/servers/app/drawing/DrawingEngine.cpp
+++ b/src/servers/app/drawing/DrawingEngine.cpp
@@ -963,49 +963,62 @@ DrawingEngine::FillRect(BRect r)
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(r);
-       r = fPainter->TransformAlignAndClipRect(r);
-       if (!r.IsValid())
+       r.left = floorf(r.left);
+       r.top = floorf(r.top);
+       r.right = ceilf(r.right);
+       r.bottom = ceilf(r.bottom);
+
+       BRect dirty = fPainter->TransformAndClipRect(r);
+       if (!dirty.IsValid())
                return;
 
        AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, r);
 
        bool doInSoftware = true;
-       if ((r.Width() + 1) * (r.Height() + 1) > 100.0) {
-               // try hardware optimized version first
-               // if the rect is large enough
-               if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
-                       if (fPainter->Pattern() == B_SOLID_HIGH
-                               && (fPainter->DrawingMode() == B_OP_COPY
-                                       || fPainter->DrawingMode() == 
B_OP_OVER)) {
-                               BRegion region(r);
-                               
region.IntersectWith(fPainter->ClippingRegion());
-                               fGraphicsCard->FillRegion(region, 
fPainter->HighColor(),
-                                       fSuspendSyncLevel == 0 || 
overlaysHider.WasHidden());
-                               doInSoftware = false;
-                       } else if (fPainter->Pattern() == B_SOLID_LOW
-                                       && fPainter->DrawingMode() == 
B_OP_COPY) {
-                               BRegion region(r);
-                               
region.IntersectWith(fPainter->ClippingRegion());
-                               fGraphicsCard->FillRegion(region, 
fPainter->LowColor(),
-                                       fSuspendSyncLevel == 0 || 
overlaysHider.WasHidden());
-                               doInSoftware = false;
+
+       if (fPainter->IsIdentityTransform())
+       {
+               // TODO the accelerated code path may also be used for 
transforms that
+               // only scale and translate (but don't shear or rotate).
+
+               if ((r.Width() + 1) * (r.Height() + 1) > 100.0) {
+                       // try hardware optimized version first
+                       // if the rect is large enough
+                       if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 
0) {
+                               if (fPainter->Pattern() == B_SOLID_HIGH
+                                       && (fPainter->DrawingMode() == B_OP_COPY
+                                               || fPainter->DrawingMode() == 
B_OP_OVER)) {
+                                       BRegion region(r);
+                                       
region.IntersectWith(fPainter->ClippingRegion());
+                                       fGraphicsCard->FillRegion(region, 
fPainter->HighColor(),
+                                               fSuspendSyncLevel == 0 || 
overlaysHider.WasHidden());
+                                       doInSoftware = false;
+                               } else if (fPainter->Pattern() == B_SOLID_LOW
+                                               && fPainter->DrawingMode() == 
B_OP_COPY) {
+                                       BRegion region(r);
+                                       
region.IntersectWith(fPainter->ClippingRegion());
+                                       fGraphicsCard->FillRegion(region, 
fPainter->LowColor(),
+                                               fSuspendSyncLevel == 0 || 
overlaysHider.WasHidden());
+                                       doInSoftware = false;
+                               }
                        }
                }
-       }
 
-       if (doInSoftware && (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
-               && fPainter->Pattern() == B_SOLID_HIGH
-               && fPainter->DrawingMode() == B_OP_INVERT) {
-               BRegion region(r);
-               region.IntersectWith(fPainter->ClippingRegion());
-               fGraphicsCard->InvertRegion(region);
-               doInSoftware = false;
+               if (doInSoftware
+                       && (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
+                       && fPainter->Pattern() == B_SOLID_HIGH
+                       && fPainter->DrawingMode() == B_OP_INVERT) {
+                       BRegion region(r);
+                       region.IntersectWith(fPainter->ClippingRegion());
+                       fGraphicsCard->InvertRegion(region);
+                       doInSoftware = false;
+               }
        }
 
        if (doInSoftware)
                fPainter->FillRect(r);
 
-       _CopyToFront(r);
+       _CopyToFront(dirty);
 }
 
 
@@ -1015,15 +1028,20 @@ DrawingEngine::FillRect(BRect r, const BGradient& 
gradient)
        ASSERT_PARALLEL_LOCKED();
 
        make_rect_valid(r);
-       r = fPainter->TransformAlignAndClipRect(r);
-       if (!r.IsValid())
+       r.left = floorf(r.left);
+       r.top = floorf(r.top);
+       r.right = ceilf(r.right);
+       r.bottom = ceilf(r.bottom);
+
+       BRect dirty = fPainter->TransformAndClipRect(r);
+       if (!dirty.IsValid())
                return;
 
-       AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, r);
+       AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, dirty);
 
        fPainter->FillRect(r, gradient);
 
-       _CopyToFront(r);
+       _CopyToFront(dirty);
 }
 
 

############################################################################

Revision:    hrev47230
Commit:      2f9ac9582db33ca8eb53261f19486abfa98b41c1
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2f9ac95
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Mon May 19 12:10:27 2014 UTC

Transformation: add one more test

* Add test for a translation that makes things that are out of view
bounds to become visible
* Fix the "rectangles" test to handle scrolling of the view. It seems
that in some cases some of the rectangles are not drawn.

The gradient and bitmap tests currently have problem with view
scrolling, but I'm not sure why.

----------------------------------------------------------------------------

diff --git a/src/tests/servers/app/transformation/main.cpp 
b/src/tests/servers/app/transformation/main.cpp
index fc22f96..b33ab7e 100644
--- a/src/tests/servers/app/transformation/main.cpp
+++ b/src/tests/servers/app/transformation/main.cpp
@@ -237,6 +237,8 @@ public:
                view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
 
                BRect rect(view->Bounds());
+               rect.OffsetTo(B_ORIGIN);
+
                rect.InsetBy(rect.Width() / 3, rect.Height() / 3);
                BPoint center(
                        rect.left + rect.Width() / 2,
@@ -449,6 +451,35 @@ public:
 };
 
 
+// #pragma mark - Clipping
+
+
+class ClippingTest : public Test {
+public:
+       ClippingTest()
+               :
+               Test("View bounds clipping")
+       {
+       }
+
+       virtual void Draw(BView* view, BRect updateRect)
+       {
+               BRect r (20, 20, 50, 50);
+               view->SetHighColor(ui_color(B_FAILURE_COLOR));
+               view->FillRect(r);
+
+               BAffineTransform transform;
+               transform.TranslateBy(400, 400);
+               view->SetTransform(transform);
+
+               // Make sure this rectangle is drawn, even when the original 
one is out
+               // of the view bounds (for example because of scrolling).
+               view->SetHighColor(ui_color(B_SUCCESS_COLOR));
+               view->FillRect(r);
+       }
+};
+
+
 // #pragma mark -
 
 
@@ -463,6 +494,7 @@ main(int argc, char** argv)
        window->AddTest(new BitmapTest());
        window->AddTest(new GradientTest());
        window->AddTest(new NestedStatesTest());
+       window->AddTest(new ClippingTest());
 
        window->SetToTest(3);
        window->Show();


Other related posts: