Usermode/AxWin4 - Working in shared memory usage
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / CSurface.cpp
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

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