2023-07-05 19:20:40 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 Jan Van Winkel <jan.van_winkel@dxplore.eu>
|
|
|
|
* Copyright (c) 2023 Nordic Semiconductor
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2024-11-10 22:25:54 +08:00
|
|
|
#include "display_sdl_bottom.h"
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <SDL.h>
|
|
|
|
#include "nsi_tracing.h"
|
|
|
|
|
2023-11-22 17:07:21 +08:00
|
|
|
int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
|
2024-01-13 05:40:13 +08:00
|
|
|
bool use_accelerator, void **window, void **renderer, void **mutex,
|
|
|
|
void **texture, void **read_texture)
|
2023-07-05 19:20:40 +08:00
|
|
|
{
|
|
|
|
*window = SDL_CreateWindow("Zephyr Display", SDL_WINDOWPOS_UNDEFINED,
|
2023-11-22 17:07:21 +08:00
|
|
|
SDL_WINDOWPOS_UNDEFINED, width * zoom_pct / 100,
|
|
|
|
height * zoom_pct / 100, SDL_WINDOW_SHOWN);
|
2023-07-05 19:20:40 +08:00
|
|
|
if (*window == NULL) {
|
|
|
|
nsi_print_warning("Failed to create SDL window: %s", SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-01-10 22:19:30 +08:00
|
|
|
if (use_accelerator) {
|
|
|
|
*renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_ACCELERATED);
|
|
|
|
} else {
|
|
|
|
*renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_SOFTWARE);
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
if (*renderer == NULL) {
|
|
|
|
nsi_print_warning("Failed to create SDL renderer: %s",
|
|
|
|
SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
*mutex = SDL_CreateMutex();
|
|
|
|
if (*mutex == NULL) {
|
|
|
|
nsi_print_warning("Failed to create SDL mutex: %s", SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2023-12-22 22:13:01 +08:00
|
|
|
SDL_RenderSetLogicalSize(*renderer, width, height);
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
*texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STATIC, width, height);
|
|
|
|
if (*texture == NULL) {
|
|
|
|
nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
*read_texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_TARGET, width, height);
|
|
|
|
if (*read_texture == NULL) {
|
|
|
|
nsi_print_warning("Failed to create SDL texture for read: %s", SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
SDL_SetRenderDrawColor(*renderer, 0, 0, 0, 0xFF);
|
|
|
|
SDL_RenderClear(*renderer);
|
|
|
|
SDL_RenderPresent(*renderer);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-11-10 22:25:54 +08:00
|
|
|
void sdl_display_write_bottom(const uint16_t height, const uint16_t width, const uint16_t x,
|
|
|
|
const uint16_t y, void *renderer, void *mutex, void *texture,
|
|
|
|
uint8_t *buf, bool display_on, bool frame_incomplete)
|
2023-07-05 19:20:40 +08:00
|
|
|
{
|
|
|
|
SDL_Rect rect;
|
2024-01-13 05:40:13 +08:00
|
|
|
int err;
|
2023-07-05 19:20:40 +08:00
|
|
|
|
|
|
|
rect.x = x;
|
|
|
|
rect.y = y;
|
|
|
|
rect.w = width;
|
|
|
|
rect.h = height;
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
err = SDL_TryLockMutex(mutex);
|
|
|
|
if (err) {
|
|
|
|
nsi_print_warning("Failed to lock SDL mutex: %s", SDL_GetError());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
SDL_UpdateTexture(texture, &rect, buf, 4 * rect.w);
|
|
|
|
|
2024-11-10 22:25:54 +08:00
|
|
|
if (display_on && !frame_incomplete) {
|
2023-07-05 19:20:40 +08:00
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
}
|
2024-01-13 05:40:13 +08:00
|
|
|
|
|
|
|
SDL_UnlockMutex(mutex);
|
2023-07-05 19:20:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int sdl_display_read_bottom(const uint16_t height, const uint16_t width,
|
|
|
|
const uint16_t x, const uint16_t y,
|
2024-01-13 05:40:13 +08:00
|
|
|
void *renderer, void *buf, uint16_t pitch,
|
|
|
|
void *mutex, void *texture, void *read_texture)
|
2023-07-05 19:20:40 +08:00
|
|
|
{
|
|
|
|
SDL_Rect rect;
|
2024-01-13 05:40:13 +08:00
|
|
|
int err;
|
2023-07-05 19:20:40 +08:00
|
|
|
|
|
|
|
rect.x = x;
|
|
|
|
rect.y = y;
|
|
|
|
rect.w = width;
|
|
|
|
rect.h = height;
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
err = SDL_TryLockMutex(mutex);
|
|
|
|
if (err) {
|
|
|
|
nsi_print_warning("Failed to lock SDL mutex: %s", SDL_GetError());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetRenderTarget(renderer, read_texture);
|
|
|
|
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
|
|
SDL_RenderReadPixels(renderer, &rect, SDL_PIXELFORMAT_ARGB8888, buf, width * 4);
|
|
|
|
|
|
|
|
SDL_SetRenderTarget(renderer, NULL);
|
|
|
|
|
|
|
|
SDL_UnlockMutex(mutex);
|
|
|
|
|
|
|
|
return err;
|
2023-07-05 19:20:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void sdl_display_blanking_off_bottom(void *renderer, void *texture)
|
|
|
|
{
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sdl_display_blanking_on_bottom(void *renderer)
|
|
|
|
{
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
}
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
|
|
|
|
void **read_texture)
|
2023-07-05 19:20:40 +08:00
|
|
|
{
|
2024-01-13 05:40:13 +08:00
|
|
|
if (*read_texture != NULL) {
|
|
|
|
SDL_DestroyTexture(*read_texture);
|
|
|
|
*read_texture = NULL;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
if (*texture != NULL) {
|
|
|
|
SDL_DestroyTexture(*texture);
|
|
|
|
*texture = NULL;
|
|
|
|
}
|
|
|
|
|
2024-01-13 05:40:13 +08:00
|
|
|
if (*mutex != NULL) {
|
|
|
|
SDL_DestroyMutex(*mutex);
|
|
|
|
*mutex = NULL;
|
|
|
|
}
|
|
|
|
|
2023-07-05 19:20:40 +08:00
|
|
|
if (*renderer != NULL) {
|
|
|
|
SDL_DestroyRenderer(*renderer);
|
|
|
|
*renderer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*window != NULL) {
|
|
|
|
SDL_DestroyWindow(*window);
|
|
|
|
*window = NULL;
|
|
|
|
}
|
|
|
|
}
|