Usermode/AxWin4 - Working in shared memory usage
authorJohn Hodge <[email protected]>
Sun, 22 Jun 2014 15:17:42 +0000 (23:17 +0800)
committerJohn Hodge <[email protected]>
Sun, 22 Jun 2014 15:17:42 +0000 (23:17 +0800)
14 files changed:
Usermode/Applications/axwin4_src/Common/include/ipc_proto.hpp
Usermode/Applications/axwin4_src/Common/include/serialisation.hpp
Usermode/Applications/axwin4_src/Common/serialisation.cpp
Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp
Usermode/Applications/axwin4_src/Server/CSurface.cpp
Usermode/Applications/axwin4_src/Server/compositor.cpp
Usermode/Applications/axwin4_src/Server/include/CSurface.hpp
Usermode/Applications/axwin4_src/Server/ipc.cpp
Usermode/Applications/axwin4_src/Server/video.cpp
Usermode/Applications/axwin4_src/UI/main.c
Usermode/Libraries/libaxwin4.so_src/include/common.hpp
Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp
Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp
Usermode/Libraries/libaxwin4.so_src/wm.cpp

index 7018a62..e47ed14 100644 (file)
@@ -26,6 +26,7 @@ enum
        IPCMSG_GETWINBUF,       // get a handle to the window's buffer
        
        // - Window drawing commands
+       IPCMSG_DAMAGERECT,      //  (u16 win, u16 x, u16 y, u16 w, u16 h) - Force reblit of area
        //IPCMSG_DRAWGROUP,     // (u16 win, u16 group_id) - (hint) Switch to this group
        //IPCMSG_CLEAR, // (u16 win) - (hint) Clear current drawing group
        IPCMSG_PUSHDATA,        // (u16 win, u16 x, u16 y, u16 w, u16 h, void data)
index 5ccef67..54293c1 100644 (file)
@@ -37,6 +37,8 @@ public:
        ::uint8_t       ReadU8();
        ::uint16_t      ReadU16();
        ::int16_t       ReadS16();
+       ::uint32_t      ReadU32();
+       ::uint64_t      ReadU64();
        const ::std::vector<uint8_t>    ReadBuffer();
        const ::std::string     ReadString();
 private:
@@ -51,6 +53,8 @@ public:
        void WriteU8(::uint8_t val);
        void WriteU16(::uint16_t val);
        void WriteS16(::int16_t val);
+       void WriteU32(::uint32_t val);
+       void WriteU64(::uint64_t val);
        void WriteBuffer(size_t n, const void* val);
        void WriteString(const char* val, size_t n);
        void WriteString(const char* val) {
index f23d5cd..016b000 100644 (file)
@@ -58,6 +58,20 @@ bool CDeserialiser::IsConsumed() const
                return ~rv_u + 1;
 }
 
+::uint32_t CDeserialiser::ReadU32()
+{
+       uint32_t rv = ReadU16();
+       rv |= (uint32_t)ReadU16() << 16;
+       return rv;
+}
+
+::uint64_t CDeserialiser::ReadU64()
+{
+       uint64_t rv = ReadU32();
+       rv |= (uint64_t)ReadU32() << 32;
+       return rv;
+}
+
 const ::std::vector<uint8_t> CDeserialiser::ReadBuffer()
 {
        RangeCheck("CDeserialiser::ReadBuffer(len)", 2);
@@ -116,6 +130,20 @@ void CSerialiser::WriteS16(::int16_t Value)
        }
 }
 
+void CSerialiser::WriteU32(::uint32_t Value)
+{
+       m_data.push_back(Value & 0xFF);
+       m_data.push_back(Value >>  8);
+       m_data.push_back(Value >> 16);
+       m_data.push_back(Value >> 24);
+}
+
+void CSerialiser::WriteU64(::uint64_t Value)
+{
+       WriteU32(Value);
+       WriteU32(Value>>32);
+}
+
 void CSerialiser::WriteBuffer(size_t n, const void* val)
 {
        const uint8_t*  val8 = static_cast<const uint8_t*>(val);
index df94958..867c491 100644 (file)
@@ -98,7 +98,7 @@ void CClient_AcessIPCPipe::SendMessage(CSerialiser& message)
        const ::std::vector<uint8_t>&   data = message.Compact();
        
        _SysDebug("CClient_AcessIPCPipe::SendMessage - %i bytes to %i", data.size(), m_fd);
-       _SysDebugHex("CClient_AcessIPCPipe::SendMessage", data.data(), data.size());
+       //_SysDebugHex("CClient_AcessIPCPipe::SendMessage", data.data(), data.size());
        _SysWrite(m_fd, data.data(), data.size());
 }
 
@@ -109,7 +109,7 @@ void CClient_AcessIPCPipe::HandleReceive()
        if( len == (size_t)-1 )
                throw ::std::system_error(errno, ::std::system_category());
        //_SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
-       //_SysDebugHex("CClient_AcessIPCPipe::HandleReceive", m_rxbuf.data(), len);
+       //_SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
        rxbuf.resize(len);
        
        CDeserialiser   msg( ::std::move(rxbuf) );
index 6d4b090..07d8bfb 100644 (file)
@@ -9,11 +9,15 @@
 #include <cassert>
 #include <stdexcept>
 #include <cstring>
+#include <system_error>
+#include <cerrno>
 
 namespace AxWin {
 
 CSurface::CSurface(int x, int y, unsigned int w, unsigned int h):
-       m_rect(x,y, w,h)
+       m_rect(x,y, w,h),
+       m_fd(-1),
+       m_data(0)
 {
        if( w > 0 && h > 0 )
        {
@@ -25,18 +29,39 @@ CSurface::~CSurface()
 {
 }
 
-void CSurface::Resize(unsigned int W, unsigned int H)
+uint64_t CSurface::GetSHMHandle()
 {
-       // Easy realloc
-       // TODO: Should I maintain window contents sanely? NOPE!
+       // 1. Free local buffer
        delete m_data;
-       m_data = new uint32_t[W * H];
+       // 2. Allocate a copy in SHM
+       m_fd = _SysOpen("/Devices/shm/anon", OPENFLAG_WRITE|OPENFLAG_READ);
+       if(m_fd==-1)    throw ::std::system_error(errno, ::std::system_category());
+       size_t  size = m_rect.m_w*m_rect.m_h*4;
+       _SysTruncate(m_fd, size);
+       // 3. mmap shm copy
+       m_data = static_cast<uint32_t*>( _SysMMap(nullptr, size, MMAP_PROT_WRITE, 0, m_fd, 0) );
+       if(!m_data)     throw ::std::system_error(errno, ::std::system_category());
+       return _SysMarshalFD(m_fd);
+}
+
+void CSurface::Resize(unsigned int W, unsigned int H)
+{
+       if( m_fd == -1 )
+       {
+               // Easy realloc
+               // TODO: Should I maintain window contents sanely? NOPE!
+               delete m_data;
+               m_data = new uint32_t[W * H];
+       }
+       else
+       {
+               //_SysIOCtl(m_fd, SHM_IOCTL_SETSIZE, W*H*4);
+       }
        m_rect.Resize(W, H);
 }
 
 void CSurface::DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* data)
 {
-       //_SysDebug("DrawScanline(%i,%i,%i,%p)", row, x_ofs, w, data);
        if( row >= m_rect.m_h )
                throw ::std::out_of_range("CSurface::DrawScanline row");
        if( x_ofs >= m_rect.m_w )
@@ -45,7 +70,8 @@ void CSurface::DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w
        if( w > m_rect.m_w )
                throw ::std::out_of_range("CSurface::DrawScanline width");
        
-       ::memcpy( &m_data[row*m_rect.m_w + x_ofs], data, w*4 );
+       size_t  ofs = row*m_rect.m_w + x_ofs;
+       ::memcpy( &m_data[ofs], data, w*4 );
 }
 
 const uint32_t* CSurface::GetScanline(unsigned int row, unsigned int x_ofs) const
index a5d1ff2..699b6a2 100644 (file)
@@ -97,7 +97,7 @@ void CCompositor::BlitFromSurface(const CSurface& dest, const CRect& src_rect)
        for( unsigned int i = 0; i < src_rect.m_h; i ++ )
        {
                m_video.BlitLine(
-                       dest.GetScanline(src_rect.m_y, src_rect.m_y),
+                       dest.GetScanline(src_rect.m_y, src_rect.m_x),
                        dest.m_rect.m_y + src_rect.m_y + i,
                        dest.m_rect.m_x + src_rect.m_x,
                        src_rect.m_w
index 488d4d6..6de7305 100644 (file)
@@ -13,6 +13,8 @@ class CSurface
 public:
        CSurface(int x, int y, unsigned int w, unsigned int h);
        ~CSurface();
+
+       uint64_t GetSHMHandle();
        
        void Resize(unsigned int new_w, unsigned int new_h);
        
@@ -21,6 +23,8 @@ public:
        
        CRect   m_rect;
        uint32_t*       m_data;
+private:
+       int     m_fd;
 };
 
 };     // namespace AxWin
index 732ddfd..fcd0eb9 100644 (file)
@@ -224,7 +224,21 @@ void HandleMessage_SendIPC(CClient& client, CDeserialiser& message)
 
 void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
 {
-       assert(!"TODO HandleMessage_GetWindowBuffer");
+       uint16_t        win_id = message.ReadU16();
+       _SysDebug("_SetWindowAttr: (%i)", win_id);
+       
+       CWindow*        win = client.GetWindow(win_id);
+       if(!win) {
+               throw IPC::CClientFailure("_PushData: Bad window");
+       }
+       
+       uint64_t handle = win->m_surface.GetSHMHandle();
+       
+       CSerialiser     reply;
+       reply.WriteU8(IPCMSG_REPLY);
+       reply.WriteU16(win_id);
+       reply.WriteU64(handle);
+       client.SendMessage(reply);
 }
 
 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
@@ -234,7 +248,7 @@ void HandleMessage_PushData(CClient& client, CDeserialiser& message)
        uint16_t        y = message.ReadU16();
        uint16_t        w = message.ReadU16();
        uint16_t        h = message.ReadU16();
-       _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h);
+       //_SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h);
        
        CWindow*        win = client.GetWindow(win_id);
        if(!win) {
@@ -280,6 +294,7 @@ MessageHandler_op_t *message_handlers[] = {
        [IPCMSG_GETWINATTR] = &HandleMessage_GetWindowAttr,
        [IPCMSG_SENDIPC]    = &HandleMessage_SendIPC,   // Use the GUI server for low-bandwith IPC
        [IPCMSG_GETWINBUF]  = &HandleMessage_GetWindowBuffer,
+       [IPCMSG_DAMAGERECT] = nullptr,
        [IPCMSG_PUSHDATA]   = &HandleMessage_PushData,  // to a window's buffer
        [IPCMSG_BLIT]       = &HandleMessage_Blit,      // Copy data from one part of the window to another
        [IPCMSG_DRAWCTL]    = &HandleMessage_DrawCtl,   // Draw a control
index 8d5f5dd..50686c6 100644 (file)
@@ -57,7 +57,8 @@ void CVideo::GetDims(unsigned int& w, unsigned int& h)
 void CVideo::BlitLine(const uint32_t* src, unsigned int dst_y, unsigned int dst_x, unsigned int width)
 {
        //_SysDebug("CVideo::BlitLine (%p, %i, %i, %i)", src, dst_y, dst_x, width);
-       size_t  cmdlen = sizeof(struct ptycmd_senddata)/4 + width;
+       //_SysDebugHex("CVideo::BlitLine", src, width*4);
+       size_t  cmdlen = (sizeof(struct ptycmd_senddata) + width*4)/4;
        //_SysDebug(" - Offset = %i, cmdlen = %i", (dst_y * m_width + dst_x) * 4, cmdlen);
        struct ptycmd_senddata  cmd = {
                {PTY2D_CMD_SEND, uint8_t(cmdlen & 0xFF), uint16_t(cmdlen>>8)},
@@ -66,11 +67,6 @@ void CVideo::BlitLine(const uint32_t* src, unsigned int dst_y, unsigned int dst_
        SetBufFormat(PTYBUFFMT_2DCMD);
        _SysWrite(m_fd, &cmd, sizeof(cmd));
        _SysWrite(m_fd, src, width*4);
-
-       //SetBufFormat(PTYBUFFMT_FB);
-       //_SysWriteAt(m_fd, (dst_y * m_width + dst_x) * 4, width * 4, src);
-       //_SysSeek(m_fd, (dst_y * m_width + dst_x) * 4, SEEK_SET);
-       //_SysWrite(m_fd, src, width * 4);
 }
 
 void CVideo::Flush()
index 3baf027..54eae0f 100644 (file)
@@ -23,12 +23,15 @@ int main(int argc, const char *argv[])
        AxWin4_SetWindowFlags(bgwin, AXWIN4_WNDFLAG_NODECORATE|AXWIN4_WNDFLAG_KEEPBELOW);
        AxWin4_ShowWindow(bgwin, true);
        
+       
+       uint32_t *buf = AxWin4_GetWindowBuffer(bgwin);
+       _SysDebug("buf = %p", buf);
        // Load image
        uint32_t *image = malloc(w*h*4);
        for(size_t i = 0; i < w*h; i ++ )
-               image[i] = rand();
+               image[i] = i*(0x1000000/w*h);
        
-       AxWin4_DrawBitmap(bgwin, 0, 0, w, h, (void*)image);
+       //AxWin4_DrawBitmap(bgwin, 0, 0, w, h, (void*)image);
 
        _SysDebug("Beginning queue");
        
index f0ec6d7..e3aa807 100644 (file)
@@ -14,12 +14,15 @@ namespace AxWin {
 
 extern void    SendMessage(CSerialiser& message);
 extern void    RecvMessage(CDeserialiser& message);
+extern CDeserialiser   GetSyncReply(CSerialiser& request, unsigned int Message);
 
 };
 
 struct sAxWin4_Window
 {
        unsigned int    m_id;
+        int    m_fd;
+       void    *m_buffer;
 };
 
 #endif
index 4b4bc71..87cc6c9 100644 (file)
@@ -40,7 +40,7 @@ bool CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& fds)
                        throw ::std::system_error(errno, ::std::system_category());
                rxbuf.resize(len);
                _SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
-               _SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
+               //_SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
                
                CDeserialiser   msg(rxbuf);
                ::AxWin::RecvMessage( msg );
index e074ee4..6947d29 100644 (file)
@@ -15,6 +15,7 @@ namespace AxWin {
 void _push_data(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, const void *Data)
 {
        CSerialiser     message;
+       //_SysDebug("_push_data - (%i,%i), %ix%i %p", X, Y, W, H, Data);
        message.WriteU8(IPCMSG_PUSHDATA);
        message.WriteU16(Window->m_id);
        message.WriteU16(X);
index f023ea8..fdfa32c 100644 (file)
@@ -35,6 +35,8 @@ extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
        tAxWin4_Window *ret = new tAxWin4_Window();
        gWindowList[id] = ret;
        ret->m_id = id;
+       ret->m_fd = -1;
+       ret->m_buffer = nullptr;
        // Request creation of window
        CSerialiser     message;
        message.WriteU8(IPCMSG_CREATEWIN);
@@ -97,11 +99,30 @@ extern "C" void AxWin4_SetTitle(tAxWin4_Window *Window, const char *Title)
 
 extern "C" void *AxWin4_GetWindowBuffer(tAxWin4_Window *Window)
 {
-       //if( !Window->m_buffer )
-       //{
-       //      // TODO: Support non-blocking operations        
-       //}
-       return NULL;
+       if( Window->m_fd == -1 )
+       {
+               CSerialiser     req;
+               req.WriteU8(IPCMSG_GETWINBUF);
+               req.WriteU16(Window->m_id);
+               
+               CDeserialiser   response = GetSyncReply(req, IPCMSG_GETWINBUF);
+               if( response.ReadU16() != Window->m_id ) {
+                       
+               }
+               
+               uint64_t handle = response.ReadU64();
+               Window->m_fd = _SysUnMarshalFD(handle);
+               
+               _SysDebug("AxWin4_GetWindowBuffer: %llx = %i", handle, Window->m_fd);
+       }
+
+       if( !Window->m_buffer )
+       {
+               size_t  size = 640*480*4;
+               Window->m_buffer = _SysMMap(NULL, size, MMAP_PROT_WRITE, MMAP_MAP_SHARED, Window->m_fd, 0);
+       }
+
+       return Window->m_buffer;
 }
 
 };     // namespace AxWin

UCC git Repository :: git.ucc.asn.au