cancel
Showing results for 
Search instead for 
Did you mean: 

What is the fastest/simplest way to shift a rectangle?

gfxfloro
Senior

Hi,

I've been wondering, what would be the quickest way to shift a rectangle of any size that is already on screen, and therefore in the current frambuffer one pixel column to the left, and then delete (turn white or something) the leftmost column?

So far I've found the functions copyFBRegiontoMemory and BlitCopy, but that would require to load everything and then write it again to the framebuffer. Using DMA there should be another way, which doesn't involve loading everything but simply shifting.

1 ACCEPTED SOLUTION

Accepted Solutions
gfxfloro
Senior

Just in case anybody else needs a quick solution to my (admittedly) very specific problem.

I used the animation storage to buffer my rectangle and then transferred it 1 pixel to the left to the framebuffer again like so:

touchgfx::Rect rectToShift(this->x+1, this->y, this->width-1, this->height);
uint16_t* anim_ptr = touchgfx::HAL::getInstance()->getAnimationStorage();
anim_ptr = touchgfx::HAL::getInstance()->copyFBRegionToMemory(rectToShift, anim_ptr, (uint32_t) rectToShift.width);
touchgfx::HAL::getInstance()->blitCopy(anim_ptr, this->x, this->y, this->width-1, this->height, (uint16_t) rectToShift.width, 255, true);

for this to work the animation storage has to be used by modifying hal.setFrameBufferStartAddress() in BoardConfiguration (this is all for the F469I-DISCO Board).

Obviously having two copy operations is not ideal, but it works fine.

Another solution I would have liked to use is shifting the bytes in the framebuffer without using animationStorage like so:

touchgfx::Rect rectToShift(this->x+1, this->y, this->width-1, this->height);
uint16_t* fb;
fb = (uint16_t*) touchgfx::HAL::getInstance()->lockFrameBuffer();
 
touchgfx::HAL::getInstance()->blitCopy(fb + (this->y * 800) + (this->x), this->x, this->y, this->width-1, this->height, (uint16_t) 800, 255, true);
 
touchgfx::HAL::getInstance()->unlockFrameBuffer();

Unfortunately I soon realized that this does not work for me because I am using the 24bpp format. Having a 16-bit pointer to the framebuffer splits every second pixel in two. I have not found another method to work around this.

View solution in original post

3 REPLIES 3
HP
Senior III

the fastest way (computational wise) is probably something along the lines updating the framebuffer directly since you have direct access to the memory. fast - but not easy. maybe you could even write directly to the display..

the easiest way is most likely just to change the coordinates of the rectangle in the view of that particular screen and then invalidating the area.

TouchGFX usually runs really fast. how fast do you need it?

gfxfloro
Senior

Just quick enough so that there's no visible slowdown. When I move the rectangle to the left and then delete the leftmost column I end up pretty quickly without a rectangle 😀 . The thing is, it's not a rectangle in the touchgfx way but rather any rectangular area on the screen, that i choose, think like pulling rectangle on your dektop with the mouse to select icons. That's why I thought there would be a way to shift the framebuffer contents directly, so I would need close to no processor time.

gfxfloro
Senior

Just in case anybody else needs a quick solution to my (admittedly) very specific problem.

I used the animation storage to buffer my rectangle and then transferred it 1 pixel to the left to the framebuffer again like so:

touchgfx::Rect rectToShift(this->x+1, this->y, this->width-1, this->height);
uint16_t* anim_ptr = touchgfx::HAL::getInstance()->getAnimationStorage();
anim_ptr = touchgfx::HAL::getInstance()->copyFBRegionToMemory(rectToShift, anim_ptr, (uint32_t) rectToShift.width);
touchgfx::HAL::getInstance()->blitCopy(anim_ptr, this->x, this->y, this->width-1, this->height, (uint16_t) rectToShift.width, 255, true);

for this to work the animation storage has to be used by modifying hal.setFrameBufferStartAddress() in BoardConfiguration (this is all for the F469I-DISCO Board).

Obviously having two copy operations is not ideal, but it works fine.

Another solution I would have liked to use is shifting the bytes in the framebuffer without using animationStorage like so:

touchgfx::Rect rectToShift(this->x+1, this->y, this->width-1, this->height);
uint16_t* fb;
fb = (uint16_t*) touchgfx::HAL::getInstance()->lockFrameBuffer();
 
touchgfx::HAL::getInstance()->blitCopy(fb + (this->y * 800) + (this->x), this->x, this->y, this->width-1, this->height, (uint16_t) 800, 255, true);
 
touchgfx::HAL::getInstance()->unlockFrameBuffer();

Unfortunately I soon realized that this does not work for me because I am using the 24bpp format. Having a 16-bit pointer to the framebuffer splits every second pixel in two. I have not found another method to work around this.