mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-16 06:30:41 +00:00
WindowServer: Query driver for framebuffer offset
Depending on the driver, the second buffer may not be located right after the first, e.g. it may be page aligned. This removes this assumption and queries the driver for the appropriate offset.
This commit is contained in:
parent
fdae117600
commit
6e792553f2
|
@ -28,6 +28,16 @@ ALWAYS_INLINE int fb_set_resolution(int fd, FBResolution* info)
|
|||
return ioctl(fd, FB_IOCTL_SET_RESOLUTION, info);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE int fb_get_buffer_offset(int fd, int index, unsigned* offset)
|
||||
{
|
||||
FBBufferOffset fb_buffer_offset;
|
||||
fb_buffer_offset.buffer_index = index;
|
||||
int result = ioctl(fd, FB_IOCTL_GET_BUFFER_OFFSET, &fb_buffer_offset);
|
||||
if (result == 0)
|
||||
*offset = fb_buffer_offset.offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE int fb_get_buffer(int fd, int* index)
|
||||
{
|
||||
return ioctl(fd, FB_IOCTL_GET_BUFFER, index);
|
||||
|
|
|
@ -30,6 +30,11 @@ struct FBRect {
|
|||
unsigned height;
|
||||
};
|
||||
|
||||
struct FBBufferOffset {
|
||||
int buffer_index;
|
||||
unsigned offset;
|
||||
};
|
||||
|
||||
struct FBFlushRects {
|
||||
int buffer_index;
|
||||
unsigned count;
|
||||
|
@ -55,6 +60,7 @@ enum IOCtlNumber {
|
|||
FB_IOCTL_GET_RESOLUTION,
|
||||
FB_IOCTL_SET_RESOLUTION,
|
||||
FB_IOCTL_GET_BUFFER,
|
||||
FB_IOCTL_GET_BUFFER_OFFSET,
|
||||
FB_IOCTL_SET_BUFFER,
|
||||
FB_IOCTL_FLUSH_BUFFERS,
|
||||
SIOCSIFADDR,
|
||||
|
@ -88,6 +94,7 @@ enum IOCtlNumber {
|
|||
#define FB_IOCTL_GET_RESOLUTION FB_IOCTL_GET_RESOLUTION
|
||||
#define FB_IOCTL_SET_RESOLUTION FB_IOCTL_SET_RESOLUTION
|
||||
#define FB_IOCTL_GET_BUFFER FB_IOCTL_GET_BUFFER
|
||||
#define FB_IOCTL_GET_BUFFER_OFFSET FB_IOCTL_GET_BUFFER_OFFSET
|
||||
#define FB_IOCTL_SET_BUFFER FB_IOCTL_SET_BUFFER
|
||||
#define FB_IOCTL_FLUSH_BUFFERS FB_IOCTL_FLUSH_BUFFERS
|
||||
#define SIOCSIFADDR SIOCSIFADDR
|
||||
|
|
|
@ -87,12 +87,12 @@ void Compositor::ScreenData::init_bitmaps(Compositor& compositor, Screen& screen
|
|||
|
||||
auto size = screen.size();
|
||||
|
||||
m_front_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRx8888, size, screen.scale_factor(), screen.pitch(), screen.scanline(0));
|
||||
m_front_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRx8888, size, screen.scale_factor(), screen.pitch(), screen.scanline(0, 0));
|
||||
m_front_painter = make<Gfx::Painter>(*m_front_bitmap);
|
||||
m_front_painter->translate(-screen.rect().location());
|
||||
|
||||
if (m_screen_can_set_buffer)
|
||||
m_back_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRx8888, size, screen.scale_factor(), screen.pitch(), screen.scanline(screen.physical_height()));
|
||||
m_back_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRx8888, size, screen.scale_factor(), screen.pitch(), screen.scanline(1, 0));
|
||||
else
|
||||
m_back_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, size, screen.scale_factor());
|
||||
m_back_painter = make<Gfx::Painter>(*m_back_bitmap);
|
||||
|
|
|
@ -225,6 +225,19 @@ bool Screen::set_resolution(bool initial)
|
|||
|
||||
m_framebuffer = (Gfx::RGBA32*)mmap(nullptr, m_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_framebuffer_fd, 0);
|
||||
VERIFY(m_framebuffer && m_framebuffer != (void*)-1);
|
||||
|
||||
if (m_can_set_buffer) {
|
||||
unsigned buffer_offset = 0;
|
||||
rc = fb_get_buffer_offset(m_framebuffer_fd, 1, &buffer_offset);
|
||||
if (rc == 0) {
|
||||
m_back_buffer_offset = buffer_offset;
|
||||
} else {
|
||||
// fall back to assuming the second buffer starts right after the last line of the first
|
||||
m_back_buffer_offset = physical_resolution.pitch * physical_resolution.height;
|
||||
}
|
||||
} else {
|
||||
m_back_buffer_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_info.resolution = { physical_resolution.width, physical_resolution.height };
|
||||
|
@ -255,6 +268,15 @@ void Screen::set_buffer(int index)
|
|||
VERIFY(rc == 0);
|
||||
}
|
||||
|
||||
size_t Screen::buffer_offset(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return 0;
|
||||
if (index == 1)
|
||||
return m_back_buffer_offset;
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void ScreenInput::set_acceleration_factor(double factor)
|
||||
{
|
||||
VERIFY(factor >= mouse_accel_min && factor <= mouse_accel_max);
|
||||
|
|
|
@ -147,6 +147,7 @@ public:
|
|||
|
||||
bool can_set_buffer() { return m_can_set_buffer; }
|
||||
void set_buffer(int index);
|
||||
size_t buffer_offset(int index) const;
|
||||
|
||||
int physical_width() const { return width() * scale_factor(); }
|
||||
int physical_height() const { return height() * scale_factor(); }
|
||||
|
@ -156,7 +157,7 @@ public:
|
|||
int height() const { return m_virtual_rect.height(); }
|
||||
int scale_factor() const { return m_info.scale_factor; }
|
||||
|
||||
Gfx::RGBA32* scanline(int y);
|
||||
Gfx::RGBA32* scanline(int buffer_index, int y);
|
||||
|
||||
Gfx::IntSize physical_size() const { return { physical_width(), physical_height() }; }
|
||||
|
||||
|
@ -190,7 +191,8 @@ private:
|
|||
static Vector<int, default_scale_factors_in_use_count> s_scale_factors_in_use;
|
||||
size_t m_index { 0 };
|
||||
|
||||
size_t m_size_in_bytes;
|
||||
size_t m_size_in_bytes { 0 };
|
||||
size_t m_back_buffer_offset { 0 };
|
||||
|
||||
Gfx::RGBA32* m_framebuffer { nullptr };
|
||||
bool m_can_set_buffer { false };
|
||||
|
@ -204,9 +206,9 @@ private:
|
|||
ScreenLayout::Screen& m_info;
|
||||
};
|
||||
|
||||
inline Gfx::RGBA32* Screen::scanline(int y)
|
||||
inline Gfx::RGBA32* Screen::scanline(int buffer_index, int y)
|
||||
{
|
||||
return reinterpret_cast<Gfx::RGBA32*>(((u8*)m_framebuffer) + (y * m_pitch));
|
||||
return reinterpret_cast<Gfx::RGBA32*>(((u8*)m_framebuffer) + buffer_offset(buffer_index) + (y * m_pitch));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue