[haiku-development] Re: Implement Begin- and EndRectTracking() in the app_server

  • From: Vivek Roy <vivekroyandroid@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Fri, 14 Apr 2017 16:15:29 +0000

Greetings,

Sorry about the delay, I am caught up in college exams. I have tried to
implement the ServerOverlay and OverlayManager classes as Stephan
suggested. The DrawingEngine needs modifications too and the
ServerTokenSpace needs another constant (kOverlayToken) according to what I
have in mind.

Any suggestions?

Regards.

On Wed, Mar 29, 2017 at 10:59 PM Vivek Roy <vivekroyandroid@xxxxxxxxx>
wrote:

Hi Stephan,

I was trying to look into the code of the DrawingEngine and see how the
mouse cursor is rendered. I ended up at HWInterface.


I intended to refactor the code so that instead of the mouse-cursor being
something special which is handled directly by the DrawingEngine, there is
instead an anonymous layer of "overlays" composited onto the screen
contents in the "transfer to visible buffer" stage. The code would be
changed to handle any number of "overlays" and the mouse cursor and
tracking rect would just be two examples.


As far as understood, to refactor the code so that the mouse cursor is not
a special case, we need to make changes to the HWInterface.cpp in the
app_server. Tell me if I am wrong and there is some other file which you
intended to refactor for this functionality (or maybe more than one file
needs to be changed).

Thanks,
Vivek

#include "ServerOverlay.h"
#include "OverlayManager.h"

#include <string.h>

ServerOverlay::ServerOverlay(BRect r, color_space space,
                int32 flags, int32 bytesPerRow, screen_id screen)
        :
        ServerBitmap(r, space, flags, bytesPerRow, screen),
        fOwningTeam(-1),
        fManager(NULL)
{
        AllocateBuffer();
}

ServerOverlay::ServerOverlay(const uint8* data, uint32 width,
                uint32 height, color_space format)
        :
        ServerBitmap(BRect(0, 0, width - 1, height - 1),
                format, 0),
        fOwningTeam(-1),
        fManager(NULL)
{
        AllocateBuffer();
        if (Bits())
                memcpy(Bits(), data, BitsLength());
}

ServerOverlay::ServerOverlay(const ServerOverlay* overlay)
        :
        ServerBitmap(overlay),
        fOwningTeam(-1),
        fManager(NULL)
{
        AllocateBuffer();

        if (overlay) {
                if (Bits() && overlay->Bits())
                        memcpy(Bits(), overlay->Bits(), BitsLength());
        }
}

ServerOverlay::~ServerOverlay()
{
}

void
ServerOverlay::AttachToManager(OverlayManager* manager)
{
        fManager = manager;
}

void
ServerOverlay::LastReferenceReleased()
{
        if (fManager != NULL && fManager->RemoveOverlay(this))
                delete this;
}

#ifndef OVERLAY_MANAGER_H
#define OVERLAY_MANAGER_H

#include <List.h>
#include <Locker.h>

#include <TokenSpace.h>

using BPrivate::BTokenSpace;
class ServerOverlay;

class OverlayManager : public BLocker {
public:
                                                                
OverlayManager();
                                                                
~OverlayManager();

                        ServerOverlay*          CreateOverlay(team_id 
clientTeam,
                                                                        const 
uint8* overlayData,
                                                                        uint32 
width, uint32 height,
                                                                        
color_space format);

                        int32                           
AddOverlay(ServerOverlay* overlay,
                                                                        int32 
token = -1);
                        void                            DeleteOverlays(team_id 
team);

                        bool                            
RemoveOverlay(ServerOverlay* overlay);

                        ServerOverlay*          FindOverlay(int32 token);

private:
                        void                            
_InitOverlay(ServerOverlay*& overlayMember,
                                                                        const 
uint8* overlayBits,
                                                                        const 
uint32 width, const uint32 height,
                                                                        const 
color_space format, int32 token);
                        void                            
_RemoveOverlay(ServerOverlay* overlay);

private:
                        BList                           fOverlayList;
                        BTokenSpace                     fTokenSpace;
};

#endif // OVERLAY_MANAGER_H#ifndef SERVER_OVERLAY_H
#define SERVER_OVERLAY_H

#include "ServerBitmap.h"

class OverlayManager;

class ServerOverlay : public ServerBitmap {
public:
                                                                
ServerOverlay(BRect r, color_space space,
                                                                        int32 
flags, int32 bytesPerRow = -1,
                                                                        
screen_id screen = B_MAIN_SCREEN_ID);
                                                                
ServerOverlay(const uint8* data,
                                                                        uint32 
width, uint32 height,
                                                                        
color_space format);
                                                                
ServerOverlay(const ServerOverlay* overlay);
        virtual                                         ~ServerOverlay();

                        void                            SetOwningTeam(team_id 
tid)
                                                                        { 
fOwningTeam = tid; }
                        team_id                         OwningTeam() const
                                                                        { 
return fOwningTeam; }

                        int32                           Token() const
                                                                        { 
return fToken; }

                        void                            
AttachedToManager(ServerOverlayManager* manager);

protected:
        virtual void                            LastReferenceReleased();

private:
        friend class ServerOverlayManager;

                        team_id                         fOwningTeam;
                        OverlayManager*         fManager;
};

typedef BReference<ServerOverlay> ServerOverlayReference;

#endif // SERVER_OVERLAY_H#include "OverlayManager.h"

#include "ServerOverlay.h"
#include "ServerTokenSpace.h"

#include <Autolock.h>

#include <new>
#include <stdio.h>

OverlayManager::OverlayManager()
        :
        BLocker("OverlayManager")
{
}

OverlayManager::~OverlayManager()
{
        for (int32 i = 0; i < fOverlayList.CountItems(); i++)
                delete (ServerOverlay*)fOverlayList.ItemAtFast(i);
}

ServerOverlay*
OverlayManager::CreateOverlay(team_id clientTeam, const uint8* overlayData
        uint32 width, uint32 height, color_space format)
{
        if (!Lock())
                return NULL;

        ServerOverlay* overlay = new (std::nothrow) ServerOverlay(data,
                width, height, format);
        if (overlay) {
                overlay->SetOwningTeam(clientTeam);
                if (AddOverlay(overlay) < B_OK) {
                        delete overlay;
                        overlay = NULL;
                }
        }

        Unlock();

        return overlay;
}

int32
OverlayManager::AddOverlay(ServerOverlay* overlay, int32 token)
{
        if (!overlay)
                return B_BAD_VALUE;
        if (!Lock())
                return B_ERROR;

        if (!fOverlayList.AddItem(overlay)) {
                Unlock();
                return B_NO_MEMORY;
        }

        if (token == -1)
                token = fTokenSpace.NewToken(kOverlayToken, overlay);
        else
                fTokenSpace.SetToken(token, kOverlayToken, overlay);

        overlay->fToken = token;
        overlay->AttachedToManager(this);

        Unlock();

        return token;
}

bool
OverlayManager::RemoveOverlay(ServerOverlay* overlay)
{
        if (!Lock())
                return false;

        _RemoveOverlay(overlay);

        Unlock();
        return true;
}

void
OverlayManager::DeleteOverlays(team_id team)
{
        if (!Lock())
                return;

        for (int32 index = fOverlayList.CountItems(); index > 0; index--) {
                ServerOverlay* overlay = 
(ServerOverlay*)fOverlayList.ItemAtFast(index);
                if (overlay->OwningTeam() == team)
                        overlay->ReleaseReference();
        }

        Unlock();
}

ServerOverlay*
OverlayManager::FindOverlay(int32 token)
{
        if (!Lock())
                return NULL;

        ServerOverlay* overlay;
        if (fTokenSpace.GetToken(token, kOverlayToken, (void**)&overlay) != 
B_OK)
                overlay = NULL;

        Unlock();

        return overlay;
}

void
OverlayManager::_InitOverlay(ServerOverlay*& overlayMember,
        const uint8* overlayBits, const uint32 width, const uint32 height,
        const color_space format, const int32 token)
{
        if (overlayBits) {
                overlayMember = new ServerOverlay(overlayBits, width, height, 
format);
        }

        AddOverlay(overlayMember, token);
}

void
OverlayManager::_RemoveOverlay(ServerOverlay*& overlay)
{
        fOverlayList.RemoveItem(overlay);
        fTokenSpace.RemoveToken(overlay->fToken);
}

Other related posts: