cancel
Showing results for 
Search instead for 
Did you mean: 

Feature request: integer scaling for simulator rendering regardless of OS scaling

I have a high resolution PC monitor (3840x2160) and have set Windows scaling to 150% to make icons and texts in most applications readable.
Screenshots in TouchGFX simulator with F3 are pixel perfect and match what is rendered on target hardware, but rendering during simulating is done using Windows scaling, so it is not sharp (1 pixel is 1.5 pixels).
I want square pixels. So 1 pixel should be 1, 4, 9 or 16 pixels of the same color for respectively 100%,200%,300% and 400%.

I have a semi-working solution.

In Visual studio 2022 I've disabled the windows scaling like so:

unsigned_char_array_0-1743092258117.png

This renders the simulator at native resolution. So the window can be quite small.

In order to do integer scaling I've added SDL_SCALE  and modified SDL hal. I've modified my HALSDL2.cpp file like so:

static uint16_t HALSDL2__FRAME_BUFFER_WIDTH = 0;
static uint16_t HALSDL2__FRAME_BUFFER_HEIGHT = 0;
+
+static uint16_t SDL_SCALE = 2;
+
static uint16_t* single_buf = NULL;
static uint16_t* double_buf = NULL;
static uint16_t* anim_store = NULL;

#if defined(WIN32) || defined(_WIN32)
@@ -110,12 +113,14 @@ void HALSDL2::renderLCD_FrameBufferToMemory(const Rect& _rectToUpdate, uint8_t*
srcRect.y = rectToUpdate.y;
srcRect.h = rectToUpdate.height;
srcRect.w = rectToUpdate.width;

SDL_Rect dstRect = srcRect;
- dstRect.x = rectToUpdate.x + getCurrentSkinX();
- dstRect.y = rectToUpdate.y + getCurrentSkinY();
+ dstRect.x = rectToUpdate.x + getCurrentSkinX()* SDL_SCALE;
+ dstRect.y = rectToUpdate.y + getCurrentSkinY()* SDL_SCALE;
+ dstRect.h = srcRect.h * SDL_SCALE;
+ dstRect.w = srcRect.w * SDL_SCALE;

SDL_RenderCopy(simulatorRenderer, framebufferTexture, &srcRect, &dstRect);

if (isSkinActive && currentSkin != 0 && !(currentSkin->isOpaque || currentSkin->hasSemiTransparency))
{
@@ -528,12 +533,12 @@ void HALSDL2::alphaChannelCheck(SDL_Surface* surface, bool& isOpaque, bool& hasS
return;
}

bool HALSDL2::doSampleTouch(int32_t& x, int32_t& y) const
{
- x = _x - getCurrentSkinX();
- y = _y - getCurrentSkinY();
+ x = _x/ SDL_SCALE - getCurrentSkinX();
+ y = _y/ SDL_SCALE - getCurrentSkinY();

if (DISPLAY_ROTATION == rotate90)
{
int32_t tmp = x;
x = y;
@@ -796,10 +801,14 @@ void HALSDL2::recreateWindow(bool updateContent /*= true*/)
if (isSkinActive && currentSkin != 0)
{
width = currentSkin->surface->w;
height = currentSkin->surface->h;
}
+
+ width *= SDL_SCALE;
+ height *= SDL_SCALE;
+
if (isSkinActive && currentSkin != 0)

This seems to work. But I haven't fully tested it and there are some quirks.
I haven't tested if it works with portrait mode for instance.

It doesn't work well with skins. I have a skin with transparency at the outer edges. When I set the scaling to something other than 1 only the skin is rendered. If I write the skin prior to the update of the display instead of after then it does work, but then the transparent edges turn black. This is a different topic about transparent skins: https://community.st.com/t5/stm32-mcus-touchgfx-and-gui/touchgfx-simulator-skin-not-working/td-p/686222

I think it is doable to create a setting in TouchGFX designer to set scaling via a drop down menu to OS scaling(the same as now) or a specific integer scaling. 

EDIT: Fixed integer scaling with skins. Added source file of modified HALSDL2.cpp

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
0 REPLIES 0