diff options
| author | Lars Muldjord <muldjordlars@gmail.com> | 2017-03-23 19:22:38 +0100 | 
|---|---|---|
| committer | Lars Muldjord <muldjordlars@gmail.com> | 2017-03-23 19:22:38 +0100 | 
| commit | 889070f5c84f67cb52a5038fe93aca6234bbc360 (patch) | |
| tree | 5c9ccdac1c8e7c13e501c89b2fbbaffa04340391 /plugingui | |
| parent | 83745f8bf86d22936c5c2c7becc86885119f5d29 (diff) | |
| parent | 494e7218597a6cd94902b3ae6f827e74b41c00b0 (diff) | |
Merge branch 'master' of http://git.drumgizmo.org/drumgizmo
Diffstat (limited to 'plugingui')
| -rw-r--r-- | plugingui/pixelbuffer.cc | 18 | ||||
| -rw-r--r-- | plugingui/pixelbuffer.h | 37 | ||||
| -rw-r--r-- | plugingui/widget.cc | 49 | ||||
| -rw-r--r-- | plugingui/window.cc | 43 | 
4 files changed, 118 insertions, 29 deletions
| diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index bbef84c..360ad06 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -33,7 +33,7 @@  namespace GUI  { -PixelBuffer::PixelBuffer(size_t width, size_t height) +PixelBuffer::PixelBuffer(std::size_t width, std::size_t height)  	: buf(nullptr)  {  	realloc(width, height); @@ -44,7 +44,7 @@ PixelBuffer::~PixelBuffer()  	free(buf);  } -void PixelBuffer::realloc(size_t width, size_t height) +void PixelBuffer::realloc(std::size_t width, std::size_t height)  {  	free(buf);  	buf = (unsigned char *)calloc(width * height, 3); @@ -53,7 +53,7 @@ void PixelBuffer::realloc(size_t width, size_t height)  }  #define PX(k) ((x + y * width) * 3 + k) -void PixelBuffer::setPixel(size_t x, size_t y, +void PixelBuffer::setPixel(std::size_t x, std::size_t y,                             unsigned char red,                             unsigned char green,                             unsigned char blue, @@ -84,7 +84,7 @@ void PixelBuffer::setPixel(size_t x, size_t y,  	}  } -PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height) +PixelBufferAlpha::PixelBufferAlpha(std::size_t width, std::size_t height)  	: managed(true)  	, buf(nullptr)  	, x(0) @@ -101,7 +101,7 @@ PixelBufferAlpha::~PixelBufferAlpha()  	}  } -void PixelBufferAlpha::realloc(size_t width, size_t height) +void PixelBufferAlpha::realloc(std::size_t width, std::size_t height)  {  	free(buf);  	buf = (unsigned char *)calloc(width * height, 4); @@ -111,7 +111,7 @@ void PixelBufferAlpha::realloc(size_t width, size_t height)  #undef PX  #define PX(k) ((x + y * width) * 4 + k) -void PixelBufferAlpha::setPixel(size_t x, size_t y, +void PixelBufferAlpha::setPixel(std::size_t x, std::size_t y,                                  unsigned char red,                                  unsigned char green,                                  unsigned char blue, @@ -135,7 +135,7 @@ static inline void getAlpha(unsigned char _a, unsigned char _b,  	b *= (1 - a);  } -void PixelBufferAlpha::addPixel(size_t x, size_t y, +void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y,                                  unsigned char red,                                  unsigned char green,                                  unsigned char blue, @@ -172,13 +172,13 @@ void PixelBufferAlpha::addPixel(size_t x, size_t y,  	}  } -void PixelBufferAlpha::addPixel(size_t x, size_t y, const Colour& c) +void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c)  {  	addPixel(x, y,  	         c.red() * 255, c.green() * 255, c.blue() * 255, c.alpha() * 255);  } -void PixelBufferAlpha::pixel(size_t x, size_t y, +void PixelBufferAlpha::pixel(std::size_t x, std::size_t y,                               unsigned char* red,                               unsigned char* green,                               unsigned char* blue, diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index 94c5496..71869a0 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -33,47 +33,49 @@  namespace GUI  { -class PixelBuffer { +class PixelBuffer +{  public: -	PixelBuffer(size_t width, size_t height); +	PixelBuffer(std::size_t width, std::size_t height);  	~PixelBuffer(); -	void realloc(size_t width, size_t height); +	void realloc(std::size_t width, std::size_t height); -	void setPixel(size_t x, size_t y, +	void setPixel(std::size_t x, std::size_t y,  	              unsigned char red,  	              unsigned char green,  	              unsigned char blue,  	              unsigned char alpha);  	unsigned char* buf{nullptr}; -	size_t width{0}; -	size_t height{0}; +	std::size_t width{0}; +	std::size_t height{0};  }; -class PixelBufferAlpha { +class PixelBufferAlpha +{  public:  	PixelBufferAlpha() = default; -	PixelBufferAlpha(size_t width, size_t height); +	PixelBufferAlpha(std::size_t width, std::size_t height);  	~PixelBufferAlpha(); -	void realloc(size_t width, size_t height); +	void realloc(std::size_t width, std::size_t height); -	void setPixel(size_t x, size_t y, +	void setPixel(std::size_t x, std::size_t y,  	              unsigned char red,  	              unsigned char green,  	              unsigned char blue,  	              unsigned char alpha); -	void addPixel(size_t x, size_t y, +	void addPixel(std::size_t x, std::size_t y,  	              unsigned char red,  	              unsigned char green,  	              unsigned char blue,  	              unsigned char alpha); -	void addPixel(size_t x, size_t y, const Colour& c); +	void addPixel(std::size_t x, std::size_t y, const Colour& c); -	void pixel(size_t x, size_t y, +	void pixel(std::size_t x, std::size_t y,  	           unsigned char* red,  	           unsigned char* green,  	           unsigned char* blue, @@ -86,6 +88,15 @@ public:  	int x{0};  	int y{0};  	bool dirty{true}; +	bool visible{true}; + +	// Add optional dirty rect that this pixelbuffer took up since it was last +	// rendered. Make sure to update this list on resize and/or move. +	std::size_t last_width{0}; +	std::size_t last_height{0}; +	int last_x{0}; +	int last_y{0}; +	bool has_last{false};  };  } // GUI:: diff --git a/plugingui/widget.cc b/plugingui/widget.cc index 7d92a22..00acfbf 100644 --- a/plugingui/widget.cc +++ b/plugingui/widget.cc @@ -42,6 +42,9 @@ Widget::Widget(Widget* parent)  		parent->addChild(this);  		_window = parent->window();  	} + +	pixbuf.x = translateToWindowX(); +	pixbuf.y = translateToWindowY();  }  Widget::~Widget() @@ -64,12 +67,14 @@ void Widget::hide()  void Widget::setVisible(bool visible)  { -	_visible = visible; - -	if(visible) +	if(_visible == visible)  	{ -		redraw(); +		return;  	} + +	_visible = visible; +	pixbuf.visible = visible; +	redraw();  }  bool Widget::visible() const @@ -130,7 +135,20 @@ void Widget::resize(std::size_t width, std::size_t height)  	_width = width;  	_height = height; + +	// Store old size/position in pixelbuffer for rendering invalidation. +	if(!pixbuf.has_last) +	{ +		pixbuf.last_width = pixbuf.width; +		pixbuf.last_height = pixbuf.height; +		pixbuf.last_x = pixbuf.x; +		pixbuf.last_y = pixbuf.y; +		pixbuf.has_last = true; +	} +  	pixbuf.realloc(width, height); +	pixbuf.x = translateToWindowX(); +	pixbuf.y = translateToWindowY();  	redraw();  	sizeChangeNotifier(width, height);  } @@ -145,6 +163,20 @@ void Widget::move(int x, int y)  	_x = x;  	_y = y; + +	// Store old size/position in pixelbuffer for rendering invalidation. +	if(!pixbuf.has_last) +	{ +		pixbuf.last_width = pixbuf.width; +		pixbuf.last_height = pixbuf.height; +		pixbuf.last_x = pixbuf.x; +		pixbuf.last_y = pixbuf.y; +		pixbuf.has_last = true; +	} + +	//pixbuf.x = translateToWindowX(); +	//pixbuf.y = translateToWindowY(); +  	positionChangeNotifier(x, y);  } @@ -216,11 +248,14 @@ std::vector<PixelBufferAlpha*> Widget::getPixelBuffers()  		dirty = false;  	} -	pixelBuffers.push_back(&pixbuf); +	if(pixbuf.dirty || visible()) +	{ +		pixelBuffers.push_back(&pixbuf); +	} -	for(auto child : children) +	if(visible())  	{ -		if(child->visible()) +		for(auto child : children)  		{  			auto childPixelBuffers = child->getPixelBuffers();  			pixelBuffers.insert(pixelBuffers.end(), diff --git a/plugingui/window.cc b/plugingui/window.cc index d4046c2..8bc5c62 100644 --- a/plugingui/window.cc +++ b/plugingui/window.cc @@ -262,10 +262,50 @@ bool Window::updateBuffer()  				};  			}  		} + +		if(pixel_buffer->has_last) +		{ +			auto x1 = (std::size_t)pixel_buffer->last_x; +			auto x2 = (std::size_t)(pixel_buffer->last_x + pixel_buffer->last_width); +			auto y1 = (std::size_t)pixel_buffer->last_y; +			auto y2 = (std::size_t)(pixel_buffer->last_y + pixel_buffer->last_height); + +			pixel_buffer->has_last = false; +			if(!has_dirty_rect) +			{ +				// Insert this area: +				dirty_rect = {x1, y1, x2, y2}; +				has_dirty_rect = true; +			} +			else +			{ +				// Expand existing area: +				auto x1_0 = dirty_rect.x1; +				auto y1_0 = dirty_rect.y1; +				auto x2_0 = dirty_rect.x2; +				auto y2_0 = dirty_rect.y2; +				dirty_rect = { +					(x1_0 < x1) ? x1_0 : x1, +					(y1_0 < y1) ? y1_0 : y1, +					(x2_0 > x2) ? x2_0 : x2, +					(y2_0 > y2) ? y2_0 : y2 +				}; +			} +		} +	} + +	if(!has_dirty_rect) +	{ +		return false;  	}  	for(auto& pixel_buffer : pixel_buffers)  	{ +		if(!pixel_buffer->visible) +		{ +			continue; +		} +  		int update_width = pixel_buffer->width;  		int update_height = pixel_buffer->height; @@ -308,6 +348,9 @@ bool Window::updateBuffer()  		}  	} +	dirty_rect.x2 = std::min(wpixbuf.width, dirty_rect.x2); +	dirty_rect.y2 = std::min(wpixbuf.height, dirty_rect.y2); +  	native->redraw(dirty_rect);  	needs_redraw = false; | 
