[haiku-commits] haiku: hrev46786 - src/servers/app

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 28 Jan 2014 23:58:09 +0100 (CET)

hrev46786 adds 1 changeset to branch 'master'
old head: 215119a1e73029a7165a1c01dfa3ceb4a90d44bf
new head: ad17bccf31f7fd7c9538a2915dff7314b077fc3c
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=ad17bcc+%5E215119a

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

ad17bcc: app_server: Implemented caching and updating the alpha mask.

                                      [ Stephan Aßmus <superstippi@xxxxxx> ]

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

Revision:    hrev46786
Commit:      ad17bccf31f7fd7c9538a2915dff7314b077fc3c
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ad17bcc
Author:      Stephan Aßmus <superstippi@xxxxxx>
Date:        Tue Jan 28 22:57:26 2014 UTC

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

3 files changed, 61 insertions(+), 38 deletions(-)
src/servers/app/AlphaMask.cpp    | 73 +++++++++++++++++++++---------------
src/servers/app/AlphaMask.h      | 20 +++++++---
src/servers/app/ServerWindow.cpp |  6 ++-

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

diff --git a/src/servers/app/AlphaMask.cpp b/src/servers/app/AlphaMask.cpp
index 80a7fc6..6cf33d9 100644
--- a/src/servers/app/AlphaMask.cpp
+++ b/src/servers/app/AlphaMask.cpp
@@ -4,6 +4,7 @@
  *
  * Authors:
  *             Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
+ *             Stephan Aßmus <superstippi@xxxxxx>
  */
 
 
@@ -11,20 +12,27 @@
 
 #include "BitmapHWInterface.h"
 #include "BitmapManager.h"
+#include "DrawingContext.h"
 #include "DrawingEngine.h"
-#include "DrawState.h"
 #include "ServerBitmap.h"
-#include "View.h"
+#include "ServerPicture.h"
 
 
-AlphaMask::AlphaMask(View* view, ServerPicture* picture, bool inverse,
-               BPoint origin)
+AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin,
+               const DrawState& drawState)
        :
        fPicture(picture),
        fInverse(inverse),
        fOrigin(origin),
-       fView(view),
+       fDrawState(drawState),
+
+       fViewBounds(),
+       fViewOffset(),
+
        fCachedBitmap(NULL),
+       fCachedBounds(),
+       fCachedOffset(),
+
        fBuffer(),
        fCachedMask(),
        fScanline(fCachedMask)
@@ -41,21 +49,32 @@ AlphaMask::~AlphaMask()
 }
 
 
+void
+AlphaMask::Update(BRect bounds, BPoint offset)
+{
+       fViewBounds = bounds;
+       fViewOffset = offset;
+}
+
+
 scanline_unpacked_masked_type*
 AlphaMask::Generate()
 {
-//     if (fCachedBitmap != NULL) {
-//             // TODO: See if cached bitmap can actually be used. Don't use it
-//             // when view scrolling offset has changed, for example. 
Generate()
-//             // could be passed a current offset
-//             return &fScanline;
-//     }
+       if (fPicture == NULL || !fViewBounds.IsValid())
+               return NULL;
+
+       // See if a cached bitmap can be used. Don't use it when the view offset
+       // or bounds have changed.
+       if (fCachedBitmap != NULL
+               && fViewBounds == fCachedBounds && fViewOffset == 
fCachedOffset) {
+               return &fScanline;
+       }
 
        if (fCachedBitmap != NULL)
                fCachedBitmap->ReleaseReference();
        
        // If rendering the picture fails, we will draw without any clipping.
-       ServerBitmap* bitmap = _RenderPicture(fPicture, fInverse);
+       ServerBitmap* bitmap = _RenderPicture();
        if (bitmap == NULL) {
                fCachedBitmap = NULL;
                fBuffer.attach(NULL, 0, 0, 0);
@@ -63,29 +82,26 @@ AlphaMask::Generate()
        }
 
        fCachedBitmap = bitmap;
+       fCachedBounds = fViewBounds;
+       fCachedOffset = fViewOffset;
 
        fBuffer.attach(fCachedBitmap->Bits(), fCachedBitmap->Width(),
                fCachedBitmap->Height(), fCachedBitmap->BytesPerRow());
 
-       BPoint offset(B_ORIGIN);
-       fView->ConvertToScreen(&offset);
-
-       fCachedMask.attach(fBuffer, offset.x + fOrigin.x, offset.y + fOrigin.y,
-               fInverse ? 255 : 0);
+       fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x,
+               fViewOffset.y + fOrigin.y, fInverse ? 255 : 0);
 
        return &fScanline;
 }
 
 
 ServerBitmap*
-AlphaMask::_RenderPicture(ServerPicture* picture, bool inverse) const
+AlphaMask::_RenderPicture() const
 {
-       BRect bounds(fView->Bounds());
-
        // TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
        // color space, so we use 300% more memory than needed.
-       UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(bounds, 
B_RGBA32,
-               0);
+       UtilityBitmap* bitmap = new(std::nothrow) UtilityBitmap(fViewBounds,
+               B_RGBA32, 0);
        if (bitmap == NULL)
                return NULL;
 
@@ -100,31 +116,28 @@ AlphaMask::_RenderPicture(ServerPicture* picture, bool 
inverse) const
                return NULL;
        }
 
-       // Copy the current state of the client view, so we draw with the right
-       // font, color and everything
-       DrawState drawState(*fView->CurrentState());
-       engine->SetDrawState(&drawState);
+       engine->SetDrawState(&fDrawState);
 
        OffscreenContext context(engine);
        if (engine->LockParallelAccess()) {
                // FIXME ConstrainClippingRegion docs says passing NULL disables
                // all clipping. This doesn't work and will crash in Painter.
                BRegion clipping;
-               clipping.Include(bounds);
+               clipping.Include(fViewBounds);
                engine->ConstrainClippingRegion(&clipping);
-               picture->Play(&context);
+               fPicture->Play(&context);
                engine->UnlockParallelAccess();
        }
        delete engine;
 
-       if (!inverse)
+       if (!fInverse)
                return bitmap;
 
        // Compute the inverse of our bitmap. There probably is a better way.
        uint32 size = bitmap->BitsLength();
        uint8* bits = (uint8*)bitmap->Bits();
 
-       for(uint32 i = 0; i < size; i++)
+       for (uint32 i = 3; i < size; i += 4)
                bits[i] = 255 - bits[i];
 
        return bitmap;
diff --git a/src/servers/app/AlphaMask.h b/src/servers/app/AlphaMask.h
index 1b31891..9521262 100644
--- a/src/servers/app/AlphaMask.h
+++ b/src/servers/app/AlphaMask.h
@@ -8,35 +8,43 @@
 
 
 #include "agg_clipped_alpha_mask.h"
-#include "ServerBitmap.h"
 #include "ServerPicture.h"
 
+#include "DrawState.h"
 #include "drawing/Painter/defines.h"
 
 
 class ServerBitmap;
+class ServerPicture;
 
 
 class AlphaMask {
 public:
-                                                               AlphaMask(View* 
view, ServerPicture* mask,
-                                                                       bool 
inverse, BPoint origin);
+                                                               
AlphaMask(ServerPicture* mask, bool inverse,
+                                                                       BPoint 
origin, const DrawState& drawState);
                                                                ~AlphaMask();
 
+                       void                            Update(BRect bounds, 
BPoint offset);
+
                        scanline_unpacked_masked_type* Generate();
 
 private:
-                       ServerBitmap*           _RenderPicture(ServerPicture* 
picture,
-                                                                       bool 
inverse) const;
+                       ServerBitmap*           _RenderPicture() const;
 
 
 private:
                        ServerPicture*          fPicture;
                        const bool                      fInverse;
                        BPoint                          fOrigin;
-                       View*                           fView;
+                       DrawState                       fDrawState;
+
+                       BRect                           fViewBounds;
+                       BPoint                          fViewOffset;
 
                        ServerBitmap*           fCachedBitmap;
+                       BRect                           fCachedBounds;
+                       BPoint                          fCachedOffset;
+
                        agg::rendering_buffer fBuffer;
                        agg::clipped_alpha_mask fCachedMask;
                        scanline_unpacked_masked_type fScanline;
diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp
index 03354a8..81f0cca 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -1884,7 +1884,7 @@ fDesktop->LockSingleWindow();
                                break;
 
                        fCurrentView->SetAlphaMask(new(std::nothrow) AlphaMask(
-                               fCurrentView, picture, inverse, where));
+                               picture, inverse, where, 
*fCurrentView->CurrentState()));
                        _UpdateDrawState(fCurrentView);
 
                        picture->ReleaseReference();
@@ -3624,9 +3624,11 @@ ServerWindow::_UpdateDrawState(View* view)
        // is being drawn? probably not... otherwise the
        // "offsets" passed below would need to be updated again
        DrawingEngine* drawingEngine = fWindow->GetDrawingEngine();
-       if (view && drawingEngine) {
+       if (view != NULL && drawingEngine != NULL) {
                BPoint leftTop(0, 0);
                view->ConvertToScreenForDrawing(&leftTop);
+               if (view->GetAlphaMask() != NULL)
+                       view->GetAlphaMask()->Update(view->Bounds(), leftTop);
                drawingEngine->SetDrawState(view->CurrentState(), leftTop.x, 
leftTop.y);
        }
 }


Other related posts: