[haiku-commits] BRANCH looncraz-github.ScreenStream [3b9c31af129f] src/servers/app/drawing

  • From: looncraz-github.ScreenStream <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 28 Mar 2015 07:01:46 +0100 (CET)

added 1 changeset to branch 'refs/remotes/looncraz-github/ScreenStream'
old head: ae3ce3190da12590acfaee7ef0d8b7dfcdb0e320
new head: 3b9c31af129f241563a843427f274d21d68adb96
overview: https://github.com/looncraz/haiku/compare/ae3ce3190da1...3b9c31af129f

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

3b9c31af129f: Locking, Update Batching
  
  Add locking on the UpdateStream lifecycle in HWInterface
  Add bounds limiting to UpdateStream (BScreenStream to come)
  Have updates spool together in a single BRegion for up to 8888us
  so we aren't iterating through a (growing) list of UpdateStreams
  
  Still need to handle the case of premature application death, otherwise
  we will end up with stray UpdateStreams, with up to te BRegions
  allocated, and two merges per frame @ 60hz.  Wasteful.
  
  Also, experiencing random crashes, but always in malloc().  Not always
  in my call chain, either.  Only happens if a non-empty BRegion is being
  sent over a ServerLink, so there may be an issue there.  More testing to
  come tomorrow.

                                        [ looncraz <looncraz@xxxxxxxxxxxx> ]

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

Commit:      3b9c31af129f241563a843427f274d21d68adb96
Author:      looncraz <looncraz@xxxxxxxxxxxx>
Date:        Sat Mar 28 05:42:36 2015 UTC

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

4 files changed, 120 insertions(+), 31 deletions(-)
src/servers/app/drawing/HWInterface.cpp  | 64 ++++++++++++++++++++++------
src/servers/app/drawing/HWInterface.h    |  6 ++-
src/servers/app/drawing/UpdateStream.cpp | 60 ++++++++++++++++++++------
src/servers/app/drawing/UpdateStream.h   | 21 ++++++---

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

diff --git a/src/servers/app/drawing/HWInterface.cpp 
b/src/servers/app/drawing/HWInterface.cpp
index 0f63e41..4c57983 100644
--- a/src/servers/app/drawing/HWInterface.cpp
+++ b/src/servers/app/drawing/HWInterface.cpp
@@ -59,6 +59,7 @@ HWInterface::HWInterface(bool doubleBuffered, bool 
enableUpdateQueue)
        fUpdateExecutor(NULL),
        fListeners(20),
        fUpdateStreams(5),
+       fLastUpdateBatch(system_time()),
        fNextUpdateStreamID(1)
 {
        SetAsyncDoubleBuffered(doubleBuffered && enableUpdateQueue);
@@ -346,9 +347,17 @@ HWInterface::IsDoubleBuffered() const
 UpdateStream*
 HWInterface::CreateUpdateStream()
 {
-       UpdateStream* stream
-               = new(std::nothrow) UpdateStream(fNextUpdateStreamID++);
-       fUpdateStreams.AddItem(stream);
+       LockExclusiveAccess();
+       UpdateStream* stream = NULL;
+
+       if (DrawingBuffer() != NULL)
+               stream = new(std::nothrow) UpdateStream(fNextUpdateStreamID++,
+                       DrawingBuffer()->Bounds(), &fRegionPool);
+
+       if (stream != NULL)
+               fUpdateStreams.AddItem(stream);
+
+       UnlockExclusiveAccess();
        return stream;
 }
 
@@ -359,25 +368,32 @@ HWInterface::DeleteUpdateStream(UpdateStream* stream)
        if (stream == NULL)
                return B_BAD_VALUE;
 
+       status_t error = B_BAD_INDEX;
+
+       LockExclusiveAccess();
        if (fUpdateStreams.RemoveItem(stream)) {
                delete stream;
-               return B_OK;
+               error = B_OK;
        }
+       UnlockExclusiveAccess();
 
-       return B_ERROR;
+       return error;
 }
 
 
 UpdateStream*
 HWInterface::FindUpdateStream(uint32 clientID)
 {
+       LockParallelAccess();
        UpdateStream* stream = NULL;
        for (int index = 0; index < fUpdateStreams.CountItems(); ++index) {
                stream = (UpdateStream*)fUpdateStreams.ItemAt(index);
-               if (stream->ID() == clientID)
+               if (stream->ID() == clientID) {
+                       UnlockParallelAccess();
                        return stream;
+               }
        }
-
+       UnlockParallelAccess();
        return NULL;
 }
 
@@ -432,11 +448,16 @@ HWInterface::CopyBackToFront(const BRect& frame)
        RenderingBuffer* frontBuffer = FrontBuffer();
        RenderingBuffer* backBuffer = BackBuffer();
 
-       if (!backBuffer || !frontBuffer)
+       IntRect area(frame);
+
+       if (!backBuffer || !frontBuffer) {
+               if (area.IsValid())
+                       _NotifyUpdateStreams(area);
+
                return B_NO_INIT;
+       }
 
        // we need to mess with the area, but it is const
-       IntRect area(frame);
        IntRect bufferClip(backBuffer->Bounds());
 
        if (area.IsValid() && area.Intersects(bufferClip)) {
@@ -457,6 +478,7 @@ HWInterface::CopyBackToFront(const BRect& frame)
                if (cursorLocked)
                        fFloatingOverlaysLock.Unlock();
 
+               _NotifyUpdateStreams(area);
                return B_OK;
        }
        return B_BAD_VALUE;
@@ -477,19 +499,26 @@ HWInterface::_CopyBackToFront(/*const*/ BRegion& region)
                // offset to left top pixel in source buffer (always B_RGBA32)
                uint8* srcOffset = src + r.top * srcBPR + r.left * 4;
                _CopyToFront(srcOffset, srcBPR, r.left, r.top, r.right, 
r.bottom);
-               _NotifyUpdateStreams(r);
        }
 }
 
 
 void
-HWInterface::_NotifyUpdateStreams(const clipping_rect& frame)
-{
+HWInterface::_NotifyUpdateStreams(const IntRect& frame)
+{      // only called while already locked
+       if (system_time() - fLastUpdateBatch < 8888) {
+               fUpdateBatchRegion.Include((clipping_rect)frame);
+               return;
+       }
+
+       fLastUpdateBatch = system_time();
        UpdateStream* stream = NULL;
        for (int index = 0; index < fUpdateStreams.CountItems(); ++index) {
                stream = (UpdateStream*)fUpdateStreams.ItemAt(index);
-               stream->Include(frame);
+               stream->Include(fUpdateBatchRegion);
        }
+
+       fUpdateBatchRegion.MakeEmpty();
 }
 
 
@@ -1147,6 +1176,15 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* 
bitmap, const BPoint& offset)
 void
 HWInterface::_NotifyFrameBufferChanged()
 {
+       if (DrawingBuffer() != NULL) {
+               UpdateStream* stream = NULL;
+               IntRect frame = DrawingBuffer()->Bounds();
+               for (int index = 0; index < fUpdateStreams.CountItems(); 
++index) {
+                       stream = (UpdateStream*)fUpdateStreams.ItemAt(index);
+                       stream->SetFrame(frame);
+               }
+       }
+
        BList listeners(fListeners);
        int32 count = listeners.CountItems();
        for (int32 i = 0; i < count; i++) {
diff --git a/src/servers/app/drawing/HWInterface.h 
b/src/servers/app/drawing/HWInterface.h
index d405298..7f7142c 100644
--- a/src/servers/app/drawing/HWInterface.h
+++ b/src/servers/app/drawing/HWInterface.h
@@ -20,6 +20,7 @@
 
 #include "IntRect.h"
 #include "MultiLocker.h"
+#include "RegionPool.h"
 #include "ServerCursor.h"
 
 
@@ -172,7 +173,7 @@ public:
 
 protected:
        virtual void                            _CopyBackToFront(/*const*/ 
BRegion& region);
-       virtual void                            _NotifyUpdateStreams(const 
clipping_rect& frame);
+       virtual void                            _NotifyUpdateStreams(const 
IntRect& frame);
 
 public:
        // TODO: Just a quick and primitive way to get single buffered mode 
working.
@@ -269,7 +270,10 @@ private:
 
                        BList                           fListeners;
                        BList                           fUpdateStreams;
+                       BRegion                         fUpdateBatchRegion;
+                       bigtime_t                       fLastUpdateBatch;
                        uint32                          fNextUpdateStreamID;
+                       RegionPool                      fRegionPool;
 };
 
 #endif // HW_INTERFACE_H
diff --git a/src/servers/app/drawing/UpdateStream.cpp 
b/src/servers/app/drawing/UpdateStream.cpp
index 42b7a75..d11b636 100644
--- a/src/servers/app/drawing/UpdateStream.cpp
+++ b/src/servers/app/drawing/UpdateStream.cpp
@@ -15,35 +15,58 @@
 */
 
 
-UpdateStream::UpdateStream(uint32 id)
+UpdateStream::UpdateStream(uint32 id, const IntRect& frame,
+       RegionPool* regionPool)
        :
-       fID(id)
-       {}
+       fID(id),
+       fRegion(regionPool->GetRegion()),
+       fMaskRegion(NULL),
+       fFrame(regionPool->GetRegion()),
+       fRegionPool(regionPool)
+       {
+               fFrame->Set((clipping_rect&)frame);
+       }
 
 
 UpdateStream::~UpdateStream()
-{}
+{
+       fRegionPool->Recycle(fRegion);
+       fRegionPool->Recycle(fFrame);
+
+       if (fMaskRegion != NULL)
+               fRegionPool->Recycle(fMaskRegion);
+}
 
 
 void
 UpdateStream::Include(const clipping_rect& frame)
 {
-       fRegion.Include(frame);
+       fRegion->Include(frame);
+}
+
+
+void
+UpdateStream::Include(const BRegion& region)
+{
+       fRegion->Include(&region);
 }
 
 
 void
 UpdateStream::MakeEmpty()
 {
-       fRegion.MakeEmpty();
+       fRegion->MakeEmpty();
 }
 
 
 const BRegion&
 UpdateStream::GetRegion() const
 {
-       fRegion.Exclude(&fMaskRegion);
-       return fRegion;
+       if (fMaskRegion != NULL)
+               fRegion->Exclude(fMaskRegion);
+
+       fRegion->IntersectWith(fFrame);
+       return *fRegion;
 }
 
 
@@ -60,28 +83,41 @@ UpdateStream::ID() const
 void
 UpdateStream::SetMaskRegion(const BRegion& mask)
 {
-       fMaskRegion = mask;
+       if (fMaskRegion == NULL)
+               fMaskRegion = fRegionPool->GetRegion();
+
+       *fMaskRegion = mask;
 }
 
 
 void
 UpdateStream::UnsetMaskRegion()
 {
-       fMaskRegion.MakeEmpty();
+       if (fMaskRegion) {
+               fMaskRegion->MakeEmpty();
+               fRegionPool->Recycle(fMaskRegion);
+               fMaskRegion = NULL;
+       }
 }
 
 
-BRegion&
+BRegion*
 UpdateStream::GetMaskRegion()
 {
        return fMaskRegion;
 }
 
 
-const BRegion&
+const BRegion*
 UpdateStream::GetMaskRegion() const
 {
        return fMaskRegion;
 }
 
 
+void
+UpdateStream::SetFrame(const IntRect& frame)
+{
+       fFrame->Set((clipping_rect&)frame);
+}
+
diff --git a/src/servers/app/drawing/UpdateStream.h 
b/src/servers/app/drawing/UpdateStream.h
index d37dcd1..b020b0a 100644
--- a/src/servers/app/drawing/UpdateStream.h
+++ b/src/servers/app/drawing/UpdateStream.h
@@ -6,12 +6,18 @@
 #include <OS.h>
 
 
+#include "IntRect.h"
+#include "RegionPool.h"
+
+
 class UpdateStream {
 public:
-                                                               
UpdateStream(uint32 id);
+                                                               
UpdateStream(uint32 id, const IntRect& frame,
+                                                                       
RegionPool* regionPool);
                                                                ~UpdateStream();
 
                        void                            Include(const 
clipping_rect& frame);
+                       void                            Include(const BRegion& 
region);
                        void                            MakeEmpty();
 
                        const BRegion&          GetRegion() const;
@@ -20,13 +26,18 @@ public:
 
                        void                            SetMaskRegion(const 
BRegion& mask);
                        void                            UnsetMaskRegion();
-                       BRegion&                        GetMaskRegion();
-                       const BRegion&          GetMaskRegion() const;
+                       BRegion*                        GetMaskRegion();
+                       const BRegion*          GetMaskRegion() const;
+
+                       void                            SetFrame(const IntRect& 
frame);
 
 private:
                        uint32                          fID;
-       mutable BRegion                         fRegion;
-                       BRegion                         fMaskRegion;
+       mutable BRegion*                        fRegion;
+                       BRegion*                        fMaskRegion;
+                       BRegion*                        fFrame;
+
+                       RegionPool*                     fRegionPool;
 };
 
 


Other related posts:

  • » [haiku-commits] BRANCH looncraz-github.ScreenStream [3b9c31af129f] src/servers/app/drawing - looncraz-github . ScreenStream