mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	Make sure all GraphicsBitmap scanlines are 16-byte aligned.
This is a prerequisite for some optimizations.
This commit is contained in:
		
							parent
							
								
									fafdda8902
								
							
						
					
					
						commit
						cec16105cc
					
				
					 5 changed files with 29 additions and 24 deletions
				
			
		|  | @ -41,6 +41,11 @@ extern "C" void* mmx_memcpy(void* to, const void* from, size_t); | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | inline constexpr dword round_up_to_power_of_two(dword value, dword power_of_two) | ||||||
|  | { | ||||||
|  |     return ((value - 1) & ~ (power_of_two - 1)) + power_of_two; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| namespace AK { | namespace AK { | ||||||
| 
 | 
 | ||||||
| template<typename T> | template<typename T> | ||||||
|  |  | ||||||
|  | @ -473,7 +473,8 @@ Retained<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size) | ||||||
| { | { | ||||||
|     ASSERT(GEventLoop::server_pid()); |     ASSERT(GEventLoop::server_pid()); | ||||||
|     ASSERT(!size.is_empty()); |     ASSERT(!size.is_empty()); | ||||||
|     size_t size_in_bytes = size.area() * sizeof(RGBA32); |     size_t pitch = round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16); | ||||||
|  |     size_t size_in_bytes = size.height() * pitch; | ||||||
|     auto shared_buffer = SharedBuffer::create(GEventLoop::server_pid(), size_in_bytes); |     auto shared_buffer = SharedBuffer::create(GEventLoop::server_pid(), size_in_bytes); | ||||||
|     ASSERT(shared_buffer); |     ASSERT(shared_buffer); | ||||||
|     auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32; |     auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32; | ||||||
|  |  | ||||||
|  | @ -14,11 +14,10 @@ Retained<GraphicsBitmap> GraphicsBitmap::create(Format format, const Size& size) | ||||||
| 
 | 
 | ||||||
| GraphicsBitmap::GraphicsBitmap(Format format, const Size& size) | GraphicsBitmap::GraphicsBitmap(Format format, const Size& size) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_pitch(size.width() * sizeof(RGBA32)) |     , m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16)) | ||||||
|     , m_format(format) |     , m_format(format) | ||||||
| { | { | ||||||
|     size_t size_in_bytes = size.area() * sizeof(RGBA32); |     m_data = (RGBA32*)mmap(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); | ||||||
|     m_data = (RGBA32*)mmap(nullptr, size_in_bytes, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |  | ||||||
|     ASSERT(m_data && m_data != (void*)-1); |     ASSERT(m_data && m_data != (void*)-1); | ||||||
|     m_needs_munmap = true; |     m_needs_munmap = true; | ||||||
|     set_mmap_name(String::format("GraphicsBitmap [%dx%d]", width(), height()).characters()); |     set_mmap_name(String::format("GraphicsBitmap [%dx%d]", width(), height()).characters()); | ||||||
|  | @ -45,7 +44,7 @@ RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(Format format, const St | ||||||
| GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, RGBA32* data) | GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, RGBA32* data) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_data(data) |     , m_data(data) | ||||||
|     , m_pitch(size.width() * sizeof(RGBA32)) |     , m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16)) | ||||||
|     , m_format(format) |     , m_format(format) | ||||||
| { | { | ||||||
| } | } | ||||||
|  | @ -53,7 +52,7 @@ GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, RGBA32* data) | ||||||
| GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, MappedFile&& mapped_file) | GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, MappedFile&& mapped_file) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_data((RGBA32*)mapped_file.pointer()) |     , m_data((RGBA32*)mapped_file.pointer()) | ||||||
|     , m_pitch(size.width() * sizeof(RGBA32)) |     , m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16)) | ||||||
|     , m_format(format) |     , m_format(format) | ||||||
|     , m_mapped_file(move(mapped_file)) |     , m_mapped_file(move(mapped_file)) | ||||||
| { | { | ||||||
|  | @ -67,7 +66,7 @@ Retained<GraphicsBitmap> GraphicsBitmap::create_with_shared_buffer(Format format | ||||||
| GraphicsBitmap::GraphicsBitmap(Format format, Retained<SharedBuffer>&& shared_buffer, const Size& size) | GraphicsBitmap::GraphicsBitmap(Format format, Retained<SharedBuffer>&& shared_buffer, const Size& size) | ||||||
|     : m_size(size) |     : m_size(size) | ||||||
|     , m_data((RGBA32*)shared_buffer->data()) |     , m_data((RGBA32*)shared_buffer->data()) | ||||||
|     , m_pitch(size.width() * sizeof(RGBA32)) |     , m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16)) | ||||||
|     , m_format(format) |     , m_format(format) | ||||||
|     , m_shared_buffer(move(shared_buffer)) |     , m_shared_buffer(move(shared_buffer)) | ||||||
| { | { | ||||||
|  | @ -76,8 +75,7 @@ GraphicsBitmap::GraphicsBitmap(Format format, Retained<SharedBuffer>&& shared_bu | ||||||
| GraphicsBitmap::~GraphicsBitmap() | GraphicsBitmap::~GraphicsBitmap() | ||||||
| { | { | ||||||
|     if (m_needs_munmap) { |     if (m_needs_munmap) { | ||||||
|         size_t size_in_bytes = m_size.area() * sizeof(RGBA32); |         int rc = munmap(m_data, size_in_bytes()); | ||||||
|         int rc = munmap(m_data, size_in_bytes); |  | ||||||
|         ASSERT(rc == 0); |         ASSERT(rc == 0); | ||||||
|     } |     } | ||||||
|     m_data = nullptr; |     m_data = nullptr; | ||||||
|  | @ -86,6 +84,5 @@ GraphicsBitmap::~GraphicsBitmap() | ||||||
| void GraphicsBitmap::set_mmap_name(const String& name) | void GraphicsBitmap::set_mmap_name(const String& name) | ||||||
| { | { | ||||||
|     ASSERT(m_needs_munmap); |     ASSERT(m_needs_munmap); | ||||||
|     size_t size_in_bytes = m_size.area() * sizeof(RGBA32); |     ::set_mmap_name(m_data, size_in_bytes(), name.characters()); | ||||||
|     ::set_mmap_name(m_data, size_in_bytes, name.characters()); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -35,6 +35,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void set_mmap_name(const String&); |     void set_mmap_name(const String&); | ||||||
| 
 | 
 | ||||||
|  |     size_t size_in_bytes() const { return m_pitch * m_size.height() * sizeof(RGBA32); } | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     GraphicsBitmap(Format, const Size&); |     GraphicsBitmap(Format, const Size&); | ||||||
|     GraphicsBitmap(Format, const Size&, RGBA32*); |     GraphicsBitmap(Format, const Size&, RGBA32*); | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ void Painter::fill_rect_with_draw_op(const Rect& a_rect, Color color) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     RGBA32* dst = m_target->scanline(rect.top()) + rect.left(); |     RGBA32* dst = m_target->scanline(rect.top()) + rect.left(); | ||||||
|     const unsigned dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int i = rect.height() - 1; i >= 0; --i) { |     for (int i = rect.height() - 1; i >= 0; --i) { | ||||||
|         for (int j = 0; j < rect.width(); ++j) |         for (int j = 0; j < rect.width(); ++j) | ||||||
|  | @ -52,7 +52,7 @@ void Painter::fill_rect(const Rect& a_rect, Color color) | ||||||
|     ASSERT(m_target->rect().contains(rect)); |     ASSERT(m_target->rect().contains(rect)); | ||||||
| 
 | 
 | ||||||
|     RGBA32* dst = m_target->scanline(rect.top()) + rect.left(); |     RGBA32* dst = m_target->scanline(rect.top()) + rect.left(); | ||||||
|     const unsigned dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int i = rect.height() - 1; i >= 0; --i) { |     for (int i = rect.height() - 1; i >= 0; --i) { | ||||||
|         fast_dword_fill(dst, color.value(), rect.width()); |         fast_dword_fill(dst, color.value(), rect.width()); | ||||||
|  | @ -73,7 +73,7 @@ void Painter::fill_rect_with_gradient(const Rect& a_rect, Color gradient_start, | ||||||
|     int x_offset = clipped_rect.x() - rect.x(); |     int x_offset = clipped_rect.x() - rect.x(); | ||||||
| 
 | 
 | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.top()) + clipped_rect.left(); |     RGBA32* dst = m_target->scanline(clipped_rect.top()) + clipped_rect.left(); | ||||||
|     const unsigned dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     float increment = (1.0/((rect.width())/255.0)); |     float increment = (1.0/((rect.width())/255.0)); | ||||||
| 
 | 
 | ||||||
|  | @ -153,7 +153,7 @@ void Painter::draw_bitmap(const Point& p, const CharacterBitmap& bitmap, Color c | ||||||
|     const int first_column = clipped_rect.left() - rect.left(); |     const int first_column = clipped_rect.left() - rect.left(); | ||||||
|     const int last_column = clipped_rect.right() - rect.left(); |     const int last_column = clipped_rect.right() - rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
|     const char* bitmap_row = &bitmap.bits()[first_row * bitmap.width() + first_column]; |     const char* bitmap_row = &bitmap.bits()[first_row * bitmap.width() + first_column]; | ||||||
|     const size_t bitmap_skip = bitmap.width(); |     const size_t bitmap_skip = bitmap.width(); | ||||||
| 
 | 
 | ||||||
|  | @ -179,7 +179,7 @@ void Painter::draw_bitmap(const Point& p, const GlyphBitmap& bitmap, Color color | ||||||
|     const int first_column = clipped_rect.left() - dst_rect.left(); |     const int first_column = clipped_rect.left() - dst_rect.left(); | ||||||
|     const int last_column = clipped_rect.right() - dst_rect.left(); |     const int last_column = clipped_rect.right() - dst_rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int row = first_row; row <= last_row; ++row) { |     for (int row = first_row; row <= last_row; ++row) { | ||||||
|         for (int j = 0; j <= (last_column - first_column); ++j) { |         for (int j = 0; j <= (last_column - first_column); ++j) { | ||||||
|  | @ -213,8 +213,8 @@ void Painter::blit_with_opacity(const Point& position, const GraphicsBitmap& sou | ||||||
|     const int last_column = clipped_rect.right() - dst_rect.left(); |     const int last_column = clipped_rect.right() - dst_rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; |     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
|     const unsigned src_skip = source.width(); |     const unsigned src_skip = source.pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int row = first_row; row <= last_row; ++row) { |     for (int row = first_row; row <= last_row; ++row) { | ||||||
|         for (int x = 0; x <= (last_column - first_column); ++x) { |         for (int x = 0; x <= (last_column - first_column); ++x) { | ||||||
|  | @ -241,8 +241,8 @@ void Painter::blit_dimmed(const Point& position, const GraphicsBitmap& source, c | ||||||
|     const int last_column = clipped_rect.right() - dst_rect.left(); |     const int last_column = clipped_rect.right() - dst_rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; |     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
|     const unsigned src_skip = source.width(); |     const size_t src_skip = source.pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int row = first_row; row <= last_row; ++row) { |     for (int row = first_row; row <= last_row; ++row) { | ||||||
|         for (int x = 0; x <= (last_column - first_column); ++x) { |         for (int x = 0; x <= (last_column - first_column); ++x) { | ||||||
|  | @ -274,8 +274,8 @@ void Painter::blit_with_alpha(const Point& position, const GraphicsBitmap& sourc | ||||||
|     const int last_column = clipped_rect.right() - dst_rect.left(); |     const int last_column = clipped_rect.right() - dst_rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; |     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
|     const unsigned src_skip = source.width(); |     const size_t src_skip = source.pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int row = first_row; row <= last_row; ++row) { |     for (int row = first_row; row <= last_row; ++row) { | ||||||
|         for (int x = 0; x <= (last_column - first_column); ++x) { |         for (int x = 0; x <= (last_column - first_column); ++x) { | ||||||
|  | @ -309,8 +309,8 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source, const Re | ||||||
|     const int first_column = clipped_rect.left() - dst_rect.left(); |     const int first_column = clipped_rect.left() - dst_rect.left(); | ||||||
|     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); |     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(); | ||||||
|     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; |     const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column; | ||||||
|     const size_t dst_skip = m_target->width(); |     const size_t dst_skip = m_target->pitch() / sizeof(RGBA32); | ||||||
|     const unsigned src_skip = source.width(); |     const size_t src_skip = source.pitch() / sizeof(RGBA32); | ||||||
| 
 | 
 | ||||||
|     for (int row = first_row; row <= last_row; ++row) { |     for (int row = first_row; row <= last_row; ++row) { | ||||||
|         fast_dword_copy(dst, src, clipped_rect.width()); |         fast_dword_copy(dst, src, clipped_rect.width()); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling