mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
imlib/draw: Refactor draw_image to support gpu offload. (#2328)
* imlib/draw: Refactor draw_image to support gpu offload. * misc/common: Fix GPU deinit. --------- Co-authored-by: Ibrahim Abdelkader <i.abdalkader@gmail.com>
This commit is contained in:
parent
277cc9d4cb
commit
4dbc7dc2fe
@ -143,9 +143,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH 90
|
#define OMV_JPEG_QUALITY_HIGH 90
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV5640_ENABLE (1)
|
#define OMV_OV5640_ENABLE (1)
|
||||||
#define OMV_OV5640_AF_ENABLE (1)
|
#define OMV_OV5640_AF_ENABLE (1)
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
//#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Stereo Imaging
|
// Stereo Imaging
|
||||||
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
||||||
|
|
||||||
|
|||||||
@ -140,9 +140,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
//#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Stereo Imaging
|
// Stereo Imaging
|
||||||
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
||||||
|
|
||||||
|
|||||||
@ -143,9 +143,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
// #define IMLIB_ENABLE_PNG_ENCODER
|
// #define IMLIB_ENABLE_PNG_ENCODER
|
||||||
// #define IMLIB_ENABLE_PNG_DECODER
|
// #define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_GC2145_ENABLE (1)
|
#define OMV_GC2145_ENABLE (1)
|
||||||
#define OMV_GC2145_ROTATE (1)
|
#define OMV_GC2145_ROTATE (1)
|
||||||
|
|||||||
@ -143,9 +143,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
// #define IMLIB_ENABLE_PNG_ENCODER
|
// #define IMLIB_ENABLE_PNG_ENCODER
|
||||||
// #define IMLIB_ENABLE_PNG_DECODER
|
// #define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV5640_ENABLE (0)
|
#define OMV_OV5640_ENABLE (0)
|
||||||
#define OMV_OV5640_AF_ENABLE (1)
|
#define OMV_OV5640_AF_ENABLE (1)
|
||||||
|
|||||||
@ -75,9 +75,6 @@
|
|||||||
// Enable Tensor Flow
|
// Enable Tensor Flow
|
||||||
//#define IMLIB_ENABLE_TFLM
|
//#define IMLIB_ENABLE_TFLM
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Stereo Imaging
|
// Stereo Imaging
|
||||||
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
||||||
|
|
||||||
|
|||||||
@ -132,9 +132,6 @@
|
|||||||
// Enable find_hog()
|
// Enable find_hog()
|
||||||
//#define IMLIB_ENABLE_HOG
|
//#define IMLIB_ENABLE_HOG
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Stereo Imaging
|
// Stereo Imaging
|
||||||
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (60)
|
#define OMV_JPEG_QUALITY_HIGH (60)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV2640_ENABLE (1)
|
#define OMV_OV2640_ENABLE (1)
|
||||||
#define OMV_OV7725_ENABLE (1)
|
#define OMV_OV7725_ENABLE (1)
|
||||||
|
|||||||
@ -138,9 +138,6 @@
|
|||||||
// Enable find_hog()
|
// Enable find_hog()
|
||||||
// #define IMLIB_ENABLE_HOG
|
// #define IMLIB_ENABLE_HOG
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (60)
|
#define OMV_JPEG_QUALITY_HIGH (60)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV7725_ENABLE (1)
|
#define OMV_OV7725_ENABLE (1)
|
||||||
#define OMV_OV7725_PLL_CONFIG (0x81) // x6
|
#define OMV_OV7725_PLL_CONFIG (0x81) // x6
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (320 * 240 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV2640_ENABLE (1)
|
#define OMV_OV2640_ENABLE (1)
|
||||||
#define OMV_OV5640_ENABLE (1)
|
#define OMV_OV5640_ENABLE (1)
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV2640_ENABLE (1)
|
#define OMV_OV2640_ENABLE (1)
|
||||||
|
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV2640_ENABLE (1)
|
#define OMV_OV2640_ENABLE (1)
|
||||||
|
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
// #define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Enable PNG encoder/decoder
|
// Enable PNG encoder/decoder
|
||||||
#define IMLIB_ENABLE_PNG_ENCODER
|
#define IMLIB_ENABLE_PNG_ENCODER
|
||||||
#define IMLIB_ENABLE_PNG_DECODER
|
#define IMLIB_ENABLE_PNG_DECODER
|
||||||
|
|||||||
@ -24,6 +24,9 @@
|
|||||||
#define OMV_JPEG_QUALITY_HIGH (90)
|
#define OMV_JPEG_QUALITY_HIGH (90)
|
||||||
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
#define OMV_JPEG_QUALITY_THRESHOLD (1920 * 1080 * 2)
|
||||||
|
|
||||||
|
// GPU Configuration
|
||||||
|
#define OMV_GPU_ENABLE (1)
|
||||||
|
|
||||||
// Image sensor drivers configuration.
|
// Image sensor drivers configuration.
|
||||||
#define OMV_OV5640_ENABLE (1)
|
#define OMV_OV5640_ENABLE (1)
|
||||||
#define OMV_OV5640_AF_ENABLE (1)
|
#define OMV_OV5640_AF_ENABLE (1)
|
||||||
|
|||||||
@ -141,9 +141,6 @@
|
|||||||
// Enable selective_search()
|
// Enable selective_search()
|
||||||
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
//#define IMLIB_ENABLE_SELECTIVE_SEARCH
|
||||||
|
|
||||||
// Enable STM32 DMA2D
|
|
||||||
//#define IMLIB_ENABLE_DMA2D
|
|
||||||
|
|
||||||
// Stereo Imaging
|
// Stereo Imaging
|
||||||
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
// #define IMLIB_ENABLE_STEREO_DISPARITY
|
||||||
|
|
||||||
|
|||||||
39
src/omv/common/omv_gpu.h
Normal file
39
src/omv/common/omv_gpu.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the OpenMV project.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||||
|
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||||
|
*
|
||||||
|
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||||
|
*
|
||||||
|
* GPU driver.
|
||||||
|
*/
|
||||||
|
#ifndef __OMV_GPU_H__
|
||||||
|
#define __OMV_GPU_H__
|
||||||
|
#include "imlib.h"
|
||||||
|
|
||||||
|
int omv_gpu_init();
|
||||||
|
void omv_gpu_deinit();
|
||||||
|
|
||||||
|
// Draws src_rect from src_img to dst_rect in dst_img.
|
||||||
|
// If the sizes of src_rect and dst_rect are different then the image must be scaled.
|
||||||
|
// Alpha is the alpha value (0-256) to use when blending the source image with the destination image.
|
||||||
|
// If color_palette is not NULL, it is used to map the source image's 8-bit Y to an 16-bit RGB565 color.
|
||||||
|
// If alpha_palette is not NULL, it is used to map the source image's 8-bit Y to an 8-bit alpha value.
|
||||||
|
//
|
||||||
|
// Valid Hint Flags:
|
||||||
|
//
|
||||||
|
// * IMAGE_HINT_BILINEAR: Use 2D bilinear interpolation when scaling the image versus nearest-neighbor.
|
||||||
|
// * IMAGE_HINT_HMIRROR: The destination image result should be horizontally mirrored from the source image.
|
||||||
|
// * IMAGE_HINT_VFLIP: The destination image result should be vertically flipped from the source image.
|
||||||
|
// * IMAGE_HINT_BLACK_BACKGROUND: The destination image should be considered to be black (0) for alpha blending.
|
||||||
|
|
||||||
|
int omv_gpu_draw_image(image_t *src_img,
|
||||||
|
rectangle_t *src_rect,
|
||||||
|
image_t *dst_img,
|
||||||
|
rectangle_t *dst_rect,
|
||||||
|
int alpha,
|
||||||
|
const uint16_t *color_palette,
|
||||||
|
const uint8_t *alpha_palette,
|
||||||
|
image_hint_t hint);
|
||||||
|
#endif // __OMV_GPU_H__
|
||||||
@ -10,14 +10,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "imlib.h"
|
#include "imlib.h"
|
||||||
|
#include "omv_gpu.h"
|
||||||
#include "unaligned_memcpy.h"
|
#include "unaligned_memcpy.h"
|
||||||
|
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
#include STM32_HAL_H
|
|
||||||
#include "dma.h"
|
|
||||||
#include "omv_common.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *imlib_compute_row_ptr(const image_t *img, int y) {
|
void *imlib_compute_row_ptr(const image_t *img, int y) {
|
||||||
switch (img->pixfmt) {
|
switch (img->pixfmt) {
|
||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
@ -711,133 +706,7 @@ void imlib_draw_row_setup(imlib_draw_row_data_t *data) {
|
|||||||
// but with the bpp of the source image.
|
// but with the bpp of the source image.
|
||||||
size_t image_row_size = image_size(&temp) / data->dst_img->h;
|
size_t image_row_size = image_size(&temp) / data->dst_img->h;
|
||||||
|
|
||||||
data->toggle = 0;
|
data->row_buffer = fb_alloc(image_row_size, FB_ALLOC_CACHE_ALIGN);
|
||||||
data->row_buffer[0] = fb_alloc(image_row_size, FB_ALLOC_CACHE_ALIGN);
|
|
||||||
|
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
data->dma2d_enabled = false;
|
|
||||||
data->dma2d_initialized = false;
|
|
||||||
|
|
||||||
void *dst_buff = data->dst_row_override ? data->dst_row_override : data->dst_img->data;
|
|
||||||
|
|
||||||
if (data->dma2d_request && (data->dst_img->pixfmt == PIXFORMAT_RGB565) && DMA_BUFFER(dst_buff) &&
|
|
||||||
((data->src_img_pixfmt == PIXFORMAT_GRAYSCALE) ||
|
|
||||||
((data->src_img_pixfmt == PIXFORMAT_RGB565) && (data->rgb_channel < 0)
|
|
||||||
&& (data->alpha != 256) && (!data->color_palette) && (!data->alpha_palette)))) {
|
|
||||||
data->row_buffer[1] = fb_alloc(image_row_size, FB_ALLOC_CACHE_ALIGN);
|
|
||||||
data->dma2d_enabled = true;
|
|
||||||
data->dma2d_initialized = true;
|
|
||||||
|
|
||||||
memset(&data->dma2d, 0, sizeof(data->dma2d));
|
|
||||||
|
|
||||||
data->dma2d.Instance = DMA2D;
|
|
||||||
data->dma2d.Init.Mode = DMA2D_M2M;
|
|
||||||
if (data->dst_img->pixfmt != data->src_img_pixfmt) {
|
|
||||||
data->dma2d.Init.Mode = DMA2D_M2M_PFC;
|
|
||||||
}
|
|
||||||
if ((data->alpha != 256) || data->alpha_palette) {
|
|
||||||
data->dma2d.Init.Mode = DMA2D_M2M_BLEND;
|
|
||||||
}
|
|
||||||
data->dma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
|
|
||||||
data->dma2d.Init.OutputOffset = 0;
|
|
||||||
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
|
|
||||||
data->dma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;
|
|
||||||
data->dma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR;
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_Init(&data->dma2d);
|
|
||||||
|
|
||||||
data->dma2d.LayerCfg[0].InputOffset = 0;
|
|
||||||
data->dma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
|
|
||||||
data->dma2d.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
|
|
||||||
data->dma2d.LayerCfg[0].InputAlpha = data->black_background ? 0x00 : 0xff;
|
|
||||||
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
|
|
||||||
data->dma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA;
|
|
||||||
data->dma2d.LayerCfg[0].RedBlueSwap = DMA2D_RB_REGULAR;
|
|
||||||
#endif
|
|
||||||
#if defined(MCU_SERIES_H7)
|
|
||||||
data->dma2d.LayerCfg[0].ChromaSubSampling = DMA2D_NO_CSS;
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_ConfigLayer(&data->dma2d, 0);
|
|
||||||
|
|
||||||
switch (data->src_img_pixfmt) {
|
|
||||||
case PIXFORMAT_GRAYSCALE: {
|
|
||||||
data->dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_L8;
|
|
||||||
data->dma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA;
|
|
||||||
uint32_t *clut = fb_alloc(256 * sizeof(uint32_t), FB_ALLOC_CACHE_ALIGN);
|
|
||||||
|
|
||||||
if (!data->alpha_palette) {
|
|
||||||
if (!data->color_palette) {
|
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
clut[i] = (0xff << 24) | COLOR_Y_TO_RGB888(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
int pixel = data->color_palette[i];
|
|
||||||
clut[i] =
|
|
||||||
(0xff <<
|
|
||||||
24) |
|
|
||||||
(COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(
|
|
||||||
pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!data->color_palette) {
|
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
clut[i] = (data->alpha_palette[i] << 24) | COLOR_Y_TO_RGB888(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
int pixel = data->color_palette[i];
|
|
||||||
clut[i] =
|
|
||||||
(data->alpha_palette[i] <<
|
|
||||||
24) |
|
|
||||||
(COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(
|
|
||||||
pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DMA2D_CLUTCfgTypeDef cfg;
|
|
||||||
cfg.pCLUT = clut;
|
|
||||||
cfg.CLUTColorMode = DMA2D_CCM_ARGB8888;
|
|
||||||
cfg.Size = 255;
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
SCB_CleanDCache_by_Addr(clut, 256 * sizeof(uint32_t));
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_CLUTLoad(&data->dma2d, cfg, 1);
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PIXFORMAT_RGB565: {
|
|
||||||
data->dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
|
|
||||||
data->dma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data->dma2d.LayerCfg[1].InputOffset = 0;
|
|
||||||
data->dma2d.LayerCfg[1].InputAlpha = fast_roundf((data->alpha * 255) / 256.f);
|
|
||||||
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
|
|
||||||
data->dma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;
|
|
||||||
data->dma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;
|
|
||||||
#endif
|
|
||||||
#if defined(MCU_SERIES_H7)
|
|
||||||
data->dma2d.LayerCfg[1].ChromaSubSampling = DMA2D_NO_CSS;
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_ConfigLayer(&data->dma2d, 1);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// SCB_InvalidateDCache_by_Addr does nothing if dsize is 0.
|
|
||||||
data->dma2d_invalidate_dsize = 0;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
data->row_buffer[1] = data->row_buffer[0];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
data->row_buffer[1] = data->row_buffer[0];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int alpha = data->alpha, max = 256;
|
int alpha = data->alpha, max = 256;
|
||||||
|
|
||||||
@ -846,8 +715,6 @@ void imlib_draw_row_setup(imlib_draw_row_data_t *data) {
|
|||||||
max = 32;
|
max = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set smuad_alpha and smuad_alpha_palette even if we don't use them with DMA2D as we may have
|
|
||||||
// to fallback to using them if the draw_image calls imlib_draw_row_put_row_buffer().
|
|
||||||
data->smuad_alpha = data->black_background ? alpha : ((alpha << 16) | (max - alpha));
|
data->smuad_alpha = data->black_background ? alpha : ((alpha << 16) | (max - alpha));
|
||||||
|
|
||||||
if (data->alpha_palette) {
|
if (data->alpha_palette) {
|
||||||
@ -866,47 +733,7 @@ void imlib_draw_row_teardown(imlib_draw_row_data_t *data) {
|
|||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
fb_free();
|
fb_free();
|
||||||
}
|
}
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
fb_free(); // data->row_buffer
|
||||||
if (data->dma2d_initialized) {
|
|
||||||
if (!data->callback) {
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Ensures any cached reads to dst16 are dropped.
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr, data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
HAL_DMA2D_DeInit(&data->dma2d);
|
|
||||||
if (data->src_img_pixfmt == PIXFORMAT_GRAYSCALE) {
|
|
||||||
fb_free(); // clut...
|
|
||||||
}
|
|
||||||
fb_free(); // data->row_buffer[1]
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
fb_free(); // data->row_buffer[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
void imlib_draw_row_deinit_all() {
|
|
||||||
DMA2D_HandleTypeDef dma2d = {};
|
|
||||||
dma2d.Instance = DMA2D;
|
|
||||||
HAL_DMA2D_DeInit(&dma2d);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data) {
|
|
||||||
void *result = data->row_buffer[data->toggle];
|
|
||||||
data->toggle = !data->toggle;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer) {
|
|
||||||
data->row_buffer[data->toggle] = row_buffer;
|
|
||||||
data->toggle = !data->toggle;
|
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
if (data->dma2d_enabled && (!DMA_BUFFER(row_buffer))) {
|
|
||||||
data->dma2d_enabled = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws (x_end - x_start) pixels.
|
// Draws (x_end - x_start) pixels.
|
||||||
@ -944,7 +771,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
((uint32_t *) data->dst_row_override) : IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
((uint32_t *) data->dst_row_override) : IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||||
switch (data->src_img_pixfmt) {
|
switch (data->src_img_pixfmt) {
|
||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
uint32_t *src32 = (uint32_t *) data->row_buffer[!data->toggle];
|
uint32_t *src32 = (uint32_t *) data->row_buffer;
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
@ -1129,7 +956,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_GRAYSCALE: {
|
case PIXFORMAT_GRAYSCALE: {
|
||||||
uint8_t *src8 = ((uint8_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint8_t *src8 = ((uint8_t *) data->row_buffer) + x_start;
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
@ -1244,7 +1071,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_RGB565: {
|
case PIXFORMAT_RGB565: {
|
||||||
uint16_t *src16 = ((uint16_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint16_t *src16 = ((uint16_t *) data->row_buffer) + x_start;
|
||||||
if (data->rgb_channel < 0) {
|
if (data->rgb_channel < 0) {
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
@ -1734,7 +1561,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
x_start;
|
x_start;
|
||||||
switch (data->src_img_pixfmt) {
|
switch (data->src_img_pixfmt) {
|
||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
uint32_t *src32 = (uint32_t *) data->row_buffer[!data->toggle];
|
uint32_t *src32 = (uint32_t *) data->row_buffer;
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
@ -1833,7 +1660,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_GRAYSCALE: {
|
case PIXFORMAT_GRAYSCALE: {
|
||||||
uint8_t *src8 = ((uint8_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint8_t *src8 = ((uint8_t *) data->row_buffer) + x_start;
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
@ -1912,7 +1739,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_RGB565: {
|
case PIXFORMAT_RGB565: {
|
||||||
uint16_t *src16 = ((uint16_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint16_t *src16 = ((uint16_t *) data->row_buffer) + x_start;
|
||||||
if (data->rgb_channel < 0) {
|
if (data->rgb_channel < 0) {
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
@ -2282,7 +2109,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
x_start;
|
x_start;
|
||||||
switch (data->src_img_pixfmt) {
|
switch (data->src_img_pixfmt) {
|
||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
uint32_t *src32 = (uint32_t *) data->row_buffer[!data->toggle];
|
uint32_t *src32 = (uint32_t *) data->row_buffer;
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
@ -2376,54 +2203,8 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_GRAYSCALE: {
|
case PIXFORMAT_GRAYSCALE: {
|
||||||
uint8_t *src8 = ((uint8_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint8_t *src8 = ((uint8_t *) data->row_buffer) + x_start;
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
// Confirm destination row starts and end on a complete cache line.
|
|
||||||
if (data->dma2d_enabled
|
|
||||||
&& ((((uint32_t) (dst16 + x_start)) % OMV_ALLOC_ALIGNMENT)
|
|
||||||
|| (((uint32_t) (dst16 + x_end)) % OMV_ALLOC_ALIGNMENT))) {
|
|
||||||
data->dma2d_enabled = false;
|
|
||||||
}
|
|
||||||
if (data->dma2d_enabled) {
|
|
||||||
if (!data->callback) {
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Ensures any cached reads to dst16 are dropped.
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Memory referenced by src8 between (x_end - x_start) may or may not be
|
|
||||||
// cache algined. However, after being flushed it shouldn't change again
|
|
||||||
// so DMA2D can safety read the line of pixels.
|
|
||||||
SCB_CleanDCache_by_Addr((uint32_t *) src8, (x_end - x_start) * sizeof(uint8_t));
|
|
||||||
// DMA2D will overwrite this area. dst16 (x_end - x_start) must be cache
|
|
||||||
// aligned or the line of pixels will be corrutped.
|
|
||||||
// Ensures any cached writes to dst16 are dropped.
|
|
||||||
data->dma2d_invalidate_addr = (uint32_t *) dst16;
|
|
||||||
data->dma2d_invalidate_dsize = (x_end - x_start) * sizeof(uint16_t);
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_BlendingStart(&data->dma2d,
|
|
||||||
(uint32_t) src8,
|
|
||||||
(uint32_t) dst16,
|
|
||||||
(uint32_t) dst16,
|
|
||||||
x_end - x_start,
|
|
||||||
1);
|
|
||||||
if (data->callback) {
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Ensures any cached reads to dst16 are dropped.
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else if (data->smuad_alpha_palette) {
|
|
||||||
#else
|
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
#endif
|
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
if (!data->black_background) {
|
if (!data->black_background) {
|
||||||
@ -2509,7 +2290,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_RGB565: {
|
case PIXFORMAT_RGB565: {
|
||||||
uint16_t *src16 = ((uint16_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint16_t *src16 = ((uint16_t *) data->row_buffer) + x_start;
|
||||||
if (data->rgb_channel < 0) {
|
if (data->rgb_channel < 0) {
|
||||||
if (data->smuad_alpha_palette) {
|
if (data->smuad_alpha_palette) {
|
||||||
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette;
|
||||||
@ -2562,53 +2343,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
} else {
|
} else {
|
||||||
long smuad_alpha = data->smuad_alpha;
|
long smuad_alpha = data->smuad_alpha;
|
||||||
if (!data->color_palette) {
|
if (!data->color_palette) {
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
// Confirm destination row starts and end on a complete cache line.
|
|
||||||
if (data->dma2d_enabled
|
|
||||||
&& ((((uint32_t) (dst16 + x_start)) % OMV_ALLOC_ALIGNMENT)
|
|
||||||
|| (((uint32_t) (dst16 + x_end)) % OMV_ALLOC_ALIGNMENT))) {
|
|
||||||
data->dma2d_enabled = false;
|
|
||||||
}
|
|
||||||
if (data->dma2d_enabled) {
|
|
||||||
if (!data->callback) {
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Ensures any cached reads to dst16 are dropped.
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Memory referenced by src16 between (x_end - x_start) may or may not be
|
|
||||||
// cache algined. However, after being flushed it shouldn't change again
|
|
||||||
// so DMA2D can safety read the line of pixels.
|
|
||||||
SCB_CleanDCache_by_Addr((uint32_t *) src16, (x_end - x_start) * sizeof(uint16_t));
|
|
||||||
// DMA2D will overwrite this area. dst16 (x_end - x_start) must be cache
|
|
||||||
// aligned or the line of pixels will be corrutped.
|
|
||||||
// Ensures any cached writes to dst16 are dropped.
|
|
||||||
data->dma2d_invalidate_addr = (uint32_t *) dst16;
|
|
||||||
data->dma2d_invalidate_dsize = (x_end - x_start) * sizeof(uint16_t);
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
HAL_DMA2D_BlendingStart(&data->dma2d,
|
|
||||||
(uint32_t) src16,
|
|
||||||
(uint32_t) dst16,
|
|
||||||
(uint32_t) dst16,
|
|
||||||
x_end - x_start,
|
|
||||||
1);
|
|
||||||
if (data->callback) {
|
|
||||||
HAL_DMA2D_PollForTransfer(&data->dma2d, 1000);
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
// Ensures any cached reads to dst16 are dropped.
|
|
||||||
SCB_InvalidateDCache_by_Addr(data->dma2d_invalidate_addr,
|
|
||||||
data->dma2d_invalidate_dsize);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else if (!data->black_background) {
|
|
||||||
#else
|
|
||||||
if (!data->black_background) {
|
if (!data->black_background) {
|
||||||
#endif
|
|
||||||
for (int x = x_start; x < x_end; x++) {
|
for (int x = x_start; x < x_end; x++) {
|
||||||
int src_pixel = *src16++;
|
int src_pixel = *src16++;
|
||||||
int dst_pixel = *dst16;
|
int dst_pixel = *dst16;
|
||||||
@ -2934,7 +2669,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
uint8_t *dst8 = (data->dst_row_override
|
uint8_t *dst8 = (data->dst_row_override
|
||||||
? ((uint8_t *) data->dst_row_override)
|
? ((uint8_t *) data->dst_row_override)
|
||||||
: IMAGE_COMPUTE_BAYER_PIXEL_ROW_PTR(data->dst_img, y_row)) + x_start;
|
: IMAGE_COMPUTE_BAYER_PIXEL_ROW_PTR(data->dst_img, y_row)) + x_start;
|
||||||
uint8_t *src8 = ((uint8_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint8_t *src8 = ((uint8_t *) data->row_buffer) + x_start;
|
||||||
unaligned_memcpy(dst8, src8, (x_end - x_start) * sizeof(uint8_t));
|
unaligned_memcpy(dst8, src8, (x_end - x_start) * sizeof(uint8_t));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2943,7 +2678,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
|
|||||||
uint16_t *dst16 = (data->dst_row_override
|
uint16_t *dst16 = (data->dst_row_override
|
||||||
? ((uint16_t *) data->dst_row_override)
|
? ((uint16_t *) data->dst_row_override)
|
||||||
: IMAGE_COMPUTE_YUV_PIXEL_ROW_PTR(data->dst_img, y_row)) + x_start;
|
: IMAGE_COMPUTE_YUV_PIXEL_ROW_PTR(data->dst_img, y_row)) + x_start;
|
||||||
uint16_t *src16 = ((uint16_t *) data->row_buffer[!data->toggle]) + x_start;
|
uint16_t *src16 = ((uint16_t *) data->row_buffer) + x_start;
|
||||||
unaligned_memcpy(dst16, src16, (x_end - x_start) * sizeof(uint16_t));
|
unaligned_memcpy(dst16, src16, (x_end - x_start) * sizeof(uint16_t));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3491,16 +3226,37 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
fb_free();
|
fb_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (&new_src_img == src_img) {
|
goto exit_cleanup;
|
||||||
fb_free();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (OMV_GPU_ENABLE == 1)
|
||||||
|
// Try to offload this to the GPU for processing.
|
||||||
|
if ((rgb_channel < 0) && (!(hint & (IMAGE_HINT_AREA | IMAGE_HINT_BICUBIC))) && (!callback)) {
|
||||||
|
rectangle_t dst_rect;
|
||||||
|
dst_rect.x = dst_x_start;
|
||||||
|
dst_rect.y = dst_y_start;
|
||||||
|
dst_rect.w = dst_x_end - dst_rect.x;
|
||||||
|
dst_rect.h = dst_y_end - dst_rect.y;
|
||||||
|
|
||||||
|
rectangle_t src_rect;
|
||||||
|
src_rect.x = src_x_accum_reset >> 16;
|
||||||
|
src_rect.y = src_y_accum_reset >> 16;
|
||||||
|
src_rect.w = ((src_x_accum_reset + (src_x_frac * dst_rect.w)) >> 16) - src_rect.x;
|
||||||
|
src_rect.h = ((src_y_accum_reset + (src_y_frac * dst_rect.h)) >> 16) - src_rect.y;
|
||||||
|
|
||||||
|
image_hint_t gpu_hint = hint & (IMAGE_HINT_BILINEAR | IMAGE_HINT_BLACK_BACKGROUND);
|
||||||
|
gpu_hint |= (dst_delta_x < 0) ? IMAGE_HINT_HMIRROR : 0;
|
||||||
|
gpu_hint |= (dst_delta_y < 0) ? IMAGE_HINT_VFLIP : 0;
|
||||||
|
|
||||||
|
if (!omv_gpu_draw_image(src_img, &src_rect, dst_img, &dst_rect, alpha, color_palette, alpha_palette, gpu_hint)) {
|
||||||
|
goto exit_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
imlib_draw_row_data_t imlib_draw_row_data;
|
imlib_draw_row_data_t imlib_draw_row_data;
|
||||||
imlib_draw_row_data.dst_img = dst_img;
|
imlib_draw_row_data.dst_img = dst_img;
|
||||||
imlib_draw_row_data.src_img_pixfmt = (!src_img->is_mutable) ? new_not_mutable_pixfmt : src_img->pixfmt;
|
imlib_draw_row_data.src_img_pixfmt = src_img->pixfmt;
|
||||||
imlib_draw_row_data.rgb_channel = rgb_channel;
|
imlib_draw_row_data.rgb_channel = rgb_channel;
|
||||||
imlib_draw_row_data.alpha = alpha;
|
imlib_draw_row_data.alpha = alpha;
|
||||||
imlib_draw_row_data.color_palette = color_palette;
|
imlib_draw_row_data.color_palette = color_palette;
|
||||||
@ -3509,11 +3265,6 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
imlib_draw_row_data.callback = callback;
|
imlib_draw_row_data.callback = callback;
|
||||||
imlib_draw_row_data.callback_arg = callback_arg;
|
imlib_draw_row_data.callback_arg = callback_arg;
|
||||||
imlib_draw_row_data.dst_row_override = dst_row_override;
|
imlib_draw_row_data.dst_row_override = dst_row_override;
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
imlib_draw_row_data.dma2d_request = (alpha != 256) || alpha_palette ||
|
|
||||||
(hint & (IMAGE_HINT_AREA | IMAGE_HINT_BICUBIC | IMAGE_HINT_BILINEAR));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
imlib_draw_row_setup(&imlib_draw_row_data);
|
imlib_draw_row_setup(&imlib_draw_row_data);
|
||||||
|
|
||||||
// Y loop iteration variables
|
// Y loop iteration variables
|
||||||
@ -3545,8 +3296,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
}
|
}
|
||||||
int height = src_y_index_end - src_y_index;
|
int height = src_y_index_end - src_y_index;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -3603,8 +3353,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
}
|
}
|
||||||
int height = src_y_index_end - src_y_index;
|
int height = src_y_index_end - src_y_index;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -3692,8 +3441,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
}
|
}
|
||||||
int height = src_y_index_end - src_y_index;
|
int height = src_y_index_end - src_y_index;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -3815,8 +3563,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
uint32_t *t_src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, src_y_index);
|
uint32_t *t_src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, src_y_index);
|
||||||
uint32_t *b_src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
uint32_t *b_src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -3973,8 +3720,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
uint8_t *t_src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, src_y_index);
|
uint8_t *t_src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, src_y_index);
|
||||||
uint8_t *b_src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
uint8_t *b_src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -4167,8 +3913,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
uint16_t *t_src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, src_y_index);
|
uint16_t *t_src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, src_y_index);
|
||||||
uint16_t *b_src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
uint16_t *b_src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, src_y_index_end);
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -4424,8 +4169,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
int dy3 = (dy2 * dy) >> 15;
|
int dy3 = (dy2 * dy) >> 15;
|
||||||
long smuad_dy_dy2 = (dy << 16) | dy2;
|
long smuad_dy_dy2 = (dy << 16) | dy2;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -4566,8 +4310,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
int dy3 = (dy2 * dy) >> 15;
|
int dy3 = (dy2 * dy) >> 15;
|
||||||
long smuad_dy_dy2 = (dy << 16) | dy2;
|
long smuad_dy_dy2 = (dy << 16) | dy2;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -4826,8 +4569,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
int dy3 = (dy2 * dy) >> 15;
|
int dy3 = (dy2 * dy) >> 15;
|
||||||
long smuad_dy_dy2 = (dy << 16) | dy2;
|
long smuad_dy_dy2 = (dy << 16) | dy2;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5164,8 +4906,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
// Cache the results of getting the source rows
|
// Cache the results of getting the source rows
|
||||||
uint32_t *src_row_ptr = ((src_y_accum >> 15) & 0x1) ? src_row_ptr_1 : src_row_ptr_0;
|
uint32_t *src_row_ptr = ((src_y_accum >> 15) & 0x1) ? src_row_ptr_1 : src_row_ptr_0;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5238,8 +4979,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
long smuad_y = (src_y_accum >> 8) & 0xff;
|
long smuad_y = (src_y_accum >> 8) & 0xff;
|
||||||
smuad_y |= (256 - smuad_y) << 16;
|
smuad_y |= (256 - smuad_y) << 16;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5326,8 +5066,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
long smuad_y = (src_y_accum >> 11) & 0x1f;
|
long smuad_y = (src_y_accum >> 11) & 0x1f;
|
||||||
smuad_y |= (32 - smuad_y) << 16;
|
smuad_y |= (32 - smuad_y) << 16;
|
||||||
|
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5415,8 +5154,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5451,8 +5189,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_BAYER_ANY: {
|
case PIXFORMAT_BAYER_ANY: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5487,8 +5224,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_YUV_ANY: {
|
case PIXFORMAT_YUV_ANY: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5528,7 +5264,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_BINARY: {
|
case PIXFORMAT_BINARY: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
imlib_draw_row_data.row_buffer = src_row_ptr;
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
// Increment offsets
|
// Increment offsets
|
||||||
@ -5542,7 +5278,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_GRAYSCALE: {
|
case PIXFORMAT_GRAYSCALE: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
imlib_draw_row_data.row_buffer = src_row_ptr;
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
// Increment offsets
|
// Increment offsets
|
||||||
@ -5556,7 +5292,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
case PIXFORMAT_RGB565: {
|
case PIXFORMAT_RGB565: {
|
||||||
while (y_not_done) {
|
while (y_not_done) {
|
||||||
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
imlib_draw_row_data.row_buffer = src_row_ptr;
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
// Increment offsets
|
// Increment offsets
|
||||||
@ -5572,14 +5308,14 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
switch (new_not_mutable_pixfmt) {
|
switch (new_not_mutable_pixfmt) {
|
||||||
case PIXFORMAT_MUTABLE_ANY: {
|
case PIXFORMAT_MUTABLE_ANY: {
|
||||||
imlib_debayer_line(dst_x_start, dst_x_end, next_src_y_index,
|
imlib_debayer_line(dst_x_start, dst_x_end, next_src_y_index,
|
||||||
imlib_draw_row_get_row_buffer(&imlib_draw_row_data),
|
imlib_draw_row_data.row_buffer,
|
||||||
new_not_mutable_pixfmt, src_img);
|
new_not_mutable_pixfmt, src_img);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_BAYER_ANY: {
|
case PIXFORMAT_BAYER_ANY: {
|
||||||
// Bayer images have the same shape as GRAYSCALE.
|
// Bayer images have the same shape as GRAYSCALE.
|
||||||
uint8_t *src_row_ptr = IMAGE_COMPUTE_BAYER_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint8_t *src_row_ptr = IMAGE_COMPUTE_BAYER_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
imlib_draw_row_data.row_buffer = src_row_ptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -5602,14 +5338,14 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
switch (new_not_mutable_pixfmt) {
|
switch (new_not_mutable_pixfmt) {
|
||||||
case PIXFORMAT_MUTABLE_ANY: {
|
case PIXFORMAT_MUTABLE_ANY: {
|
||||||
imlib_deyuv_line(dst_x_start, dst_x_end, next_src_y_index,
|
imlib_deyuv_line(dst_x_start, dst_x_end, next_src_y_index,
|
||||||
imlib_draw_row_get_row_buffer(&imlib_draw_row_data),
|
imlib_draw_row_data.row_buffer,
|
||||||
new_not_mutable_pixfmt, src_img);
|
new_not_mutable_pixfmt, src_img);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIXFORMAT_YUV_ANY: {
|
case PIXFORMAT_YUV_ANY: {
|
||||||
// YUV images have the same shape as RGB565.
|
// YUV images have the same shape as RGB565.
|
||||||
uint16_t *src_row_ptr = IMAGE_COMPUTE_YUV_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
uint16_t *src_row_ptr = IMAGE_COMPUTE_YUV_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
imlib_draw_row_data.row_buffer = src_row_ptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -5642,8 +5378,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Cache the results of getting the source row
|
// Cache the results of getting the source row
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5688,8 +5423,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Cache the results of getting the source row
|
// Cache the results of getting the source row
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5734,8 +5468,7 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Cache the results of getting the source row
|
// Cache the results of getting the source row
|
||||||
// Must be called per loop to get the address of the temp buffer to blend with
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_data.row_buffer;
|
||||||
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
|
||||||
|
|
||||||
// X loop iteration variables
|
// X loop iteration variables
|
||||||
int dst_x = dst_x_reset;
|
int dst_x = dst_x_reset;
|
||||||
@ -5778,6 +5511,9 @@ void imlib_draw_image(image_t *dst_img,
|
|||||||
}
|
}
|
||||||
|
|
||||||
imlib_draw_row_teardown(&imlib_draw_row_data);
|
imlib_draw_row_teardown(&imlib_draw_row_data);
|
||||||
|
|
||||||
|
exit_cleanup:
|
||||||
|
|
||||||
if (&new_src_img == src_img) {
|
if (&new_src_img == src_img) {
|
||||||
fb_free();
|
fb_free();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,17 +17,21 @@
|
|||||||
#include "file_utils.h"
|
#include "file_utils.h"
|
||||||
#include "imlib.h"
|
#include "imlib.h"
|
||||||
#include "omv_common.h"
|
#include "omv_common.h"
|
||||||
|
#include "omv_gpu.h"
|
||||||
#include "omv_boardconfig.h"
|
#include "omv_boardconfig.h"
|
||||||
|
|
||||||
void imlib_init_all() {
|
void imlib_init_all() {
|
||||||
|
#if (OMV_GPU_ENABLE == 1)
|
||||||
|
omv_gpu_init();
|
||||||
|
#endif
|
||||||
#if (OMV_JPEG_CODEC_ENABLE == 1)
|
#if (OMV_JPEG_CODEC_ENABLE == 1)
|
||||||
imlib_hardware_jpeg_init();
|
imlib_hardware_jpeg_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void imlib_deinit_all() {
|
void imlib_deinit_all() {
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
#if (OMV_GPU_ENABLE == 1)
|
||||||
imlib_draw_row_deinit_all();
|
omv_gpu_deinit();
|
||||||
#endif
|
#endif
|
||||||
#if (OMV_JPEG_CODEC_ENABLE == 1)
|
#if (OMV_JPEG_CODEC_ENABLE == 1)
|
||||||
imlib_hardware_jpeg_deinit();
|
imlib_hardware_jpeg_deinit();
|
||||||
|
|||||||
@ -1136,18 +1136,7 @@ typedef struct imlib_draw_row_data {
|
|||||||
void *callback; // user
|
void *callback; // user
|
||||||
void *callback_arg; // user
|
void *callback_arg; // user
|
||||||
void *dst_row_override; // user
|
void *dst_row_override; // user
|
||||||
int toggle; // private
|
void *row_buffer; // private
|
||||||
void *row_buffer[2]; // private
|
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
bool dma2d_request; // user
|
|
||||||
bool dma2d_enabled; // private
|
|
||||||
bool dma2d_initialized; // private
|
|
||||||
DMA2D_HandleTypeDef dma2d; // private
|
|
||||||
#if __DCACHE_PRESENT
|
|
||||||
void *dma2d_invalidate_addr; // private
|
|
||||||
int32_t dma2d_invalidate_dsize; // private
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
long smuad_alpha; // private
|
long smuad_alpha; // private
|
||||||
uint32_t *smuad_alpha_palette; // private
|
uint32_t *smuad_alpha_palette; // private
|
||||||
} imlib_draw_row_data_t;
|
} imlib_draw_row_data_t;
|
||||||
@ -1316,11 +1305,6 @@ void imlib_find_hog(image_t *src, rectangle_t *roi, int cell_size);
|
|||||||
void imlib_zero(image_t *img, image_t *mask, bool invert);
|
void imlib_zero(image_t *img, image_t *mask, bool invert);
|
||||||
void imlib_draw_row_setup(imlib_draw_row_data_t *data);
|
void imlib_draw_row_setup(imlib_draw_row_data_t *data);
|
||||||
void imlib_draw_row_teardown(imlib_draw_row_data_t *data);
|
void imlib_draw_row_teardown(imlib_draw_row_data_t *data);
|
||||||
#ifdef IMLIB_ENABLE_DMA2D
|
|
||||||
void imlib_draw_row_deinit_all();
|
|
||||||
#endif
|
|
||||||
void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data);
|
|
||||||
void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer);
|
|
||||||
void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data);
|
void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||||
void imlib_draw_image_get_bounds(image_t *dst_img,
|
void imlib_draw_image_get_bounds(image_t *dst_img,
|
||||||
image_t *src_img,
|
image_t *src_img,
|
||||||
|
|||||||
229
src/omv/ports/stm32/omv_gpu.c
Normal file
229
src/omv/ports/stm32/omv_gpu.c
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the OpenMV project.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||||
|
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||||
|
*
|
||||||
|
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||||
|
*
|
||||||
|
* GPU driver for STM32 port.
|
||||||
|
*/
|
||||||
|
#include "omv_boardconfig.h"
|
||||||
|
#if (OMV_GPU_ENABLE == 1)
|
||||||
|
#include "imlib.h"
|
||||||
|
|
||||||
|
#include STM32_HAL_H
|
||||||
|
#include "dma.h"
|
||||||
|
|
||||||
|
#define TIME_GPU (0)
|
||||||
|
#if (TIME_GPU == 1)
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int omv_gpu_init() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void omv_gpu_deinit() {
|
||||||
|
DMA2D_HandleTypeDef dma2d = {};
|
||||||
|
dma2d.Instance = DMA2D;
|
||||||
|
HAL_DMA2D_DeInit(&dma2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int omv_gpu_draw_image(image_t *src_img,
|
||||||
|
rectangle_t *src_rect,
|
||||||
|
image_t *dst_img,
|
||||||
|
rectangle_t *dst_rect,
|
||||||
|
int alpha,
|
||||||
|
const uint16_t *color_palette,
|
||||||
|
const uint8_t *alpha_palette,
|
||||||
|
image_hint_t hint) {
|
||||||
|
// DMA2D can only draw on RGB565 buffers and the destination/source buffers must be accessible by DMA.
|
||||||
|
if ((dst_img->pixfmt != PIXFORMAT_RGB565) || (!DMA_BUFFER(dst_img->data)) || (!DMA_BUFFER(src_img->data))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMA2D can only read from RGB565 or GRAYSCALE buffers.
|
||||||
|
// If the source image is RGB565, it must not have a color or alpha palette.
|
||||||
|
if ((src_img->pixfmt != PIXFORMAT_GRAYSCALE) &&
|
||||||
|
((src_img->pixfmt != PIXFORMAT_RGB565) || color_palette || alpha_palette)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMA2D cannot scale so ensure that the source and destination rectangles are the same size.
|
||||||
|
// The bilinear/nearest-neighbor flag doesn't matter since we can't scale.
|
||||||
|
if ((dst_rect->w != src_rect->w) || (dst_rect->h != src_rect->h)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMA2D cannot hmirror or vflip.
|
||||||
|
if (hint & (IMAGE_HINT_HMIRROR | IMAGE_HINT_VFLIP)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMA2D must always fetch the background on the F4 and F7 series so do this in software.
|
||||||
|
#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
|
||||||
|
if (hint & IMAGE_HINT_BLACK_BACKGROUND) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (TIME_GPU == 1)
|
||||||
|
mp_uint_t start = mp_hal_ticks_ms();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DMA2D_HandleTypeDef dma2d = {};
|
||||||
|
|
||||||
|
dma2d.Instance = DMA2D;
|
||||||
|
|
||||||
|
if (dst_img->pixfmt != src_img->pixfmt) {
|
||||||
|
dma2d.Init.Mode = DMA2D_M2M_PFC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((alpha != 256) || alpha_palette) {
|
||||||
|
dma2d.Init.Mode = DMA2D_M2M_BLEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MCU_SERIES_H7)
|
||||||
|
if (hint & IMAGE_HINT_BLACK_BACKGROUND) {
|
||||||
|
dma2d.Init.Mode = DMA2D_M2M_BLEND_BG;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
|
||||||
|
dma2d.Init.OutputOffset = dst_img->w - dst_rect->w;
|
||||||
|
|
||||||
|
HAL_DMA2D_Init(&dma2d);
|
||||||
|
|
||||||
|
dma2d.LayerCfg[0].InputOffset = dst_img->w - dst_rect->w;
|
||||||
|
dma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
|
||||||
|
dma2d.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
|
||||||
|
dma2d.LayerCfg[0].InputAlpha = 0xff;
|
||||||
|
|
||||||
|
HAL_DMA2D_ConfigLayer(&dma2d, 0);
|
||||||
|
|
||||||
|
if (src_img->pixfmt == PIXFORMAT_GRAYSCALE) {
|
||||||
|
dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_L8;
|
||||||
|
dma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA;
|
||||||
|
uint32_t *clut = fb_alloc(256 * sizeof(uint32_t), FB_ALLOC_CACHE_ALIGN);
|
||||||
|
|
||||||
|
if (!alpha_palette) {
|
||||||
|
if (!color_palette) {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
clut[i] = (0xff << 24) | COLOR_Y_TO_RGB888(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
int pixel = color_palette[i];
|
||||||
|
clut[i] = (0xff << 24) |
|
||||||
|
(COLOR_RGB565_TO_R8(pixel) << 16) |
|
||||||
|
(COLOR_RGB565_TO_G8(pixel) << 8) |
|
||||||
|
COLOR_RGB565_TO_B8(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!color_palette) {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
clut[i] = (alpha_palette[i] << 24) | COLOR_Y_TO_RGB888(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
int pixel = color_palette[i];
|
||||||
|
clut[i] = (alpha_palette[i] << 24) |
|
||||||
|
(COLOR_RGB565_TO_R8(pixel) << 16) |
|
||||||
|
(COLOR_RGB565_TO_G8(pixel) << 8) |
|
||||||
|
COLOR_RGB565_TO_B8(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DMA2D_CLUTCfgTypeDef cfg;
|
||||||
|
cfg.pCLUT = clut;
|
||||||
|
cfg.CLUTColorMode = DMA2D_CCM_ARGB8888;
|
||||||
|
cfg.Size = 255;
|
||||||
|
#if __DCACHE_PRESENT
|
||||||
|
SCB_CleanDCache_by_Addr(clut, 256 * sizeof(uint32_t));
|
||||||
|
#endif
|
||||||
|
HAL_DMA2D_CLUTLoad(&dma2d, cfg, 1);
|
||||||
|
HAL_DMA2D_PollForTransfer(&dma2d, 1000);
|
||||||
|
} else {
|
||||||
|
dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
|
||||||
|
dma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma2d.LayerCfg[1].InputOffset = src_img->w - src_rect->w;
|
||||||
|
dma2d.LayerCfg[1].InputAlpha = (alpha * 255) / 256;
|
||||||
|
|
||||||
|
HAL_DMA2D_ConfigLayer(&dma2d, 1);
|
||||||
|
|
||||||
|
uint16_t *dst16 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(dst_img, dst_rect->y) + dst_rect->x;
|
||||||
|
|
||||||
|
#if __DCACHE_PRESENT
|
||||||
|
// Ensures any cached writes to dst16 are flushed.
|
||||||
|
uint16_t *dst16_tmp = dst16;
|
||||||
|
for (int i = 0; i < dst_rect->h; i++) {
|
||||||
|
SCB_CleanInvalidateDCache_by_Addr(dst16_tmp, dst_rect->w * sizeof(uint16_t));
|
||||||
|
dst16_tmp += dst_img->w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t src;
|
||||||
|
|
||||||
|
if (src_img->pixfmt == PIXFORMAT_GRAYSCALE) {
|
||||||
|
uint8_t *src8 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, src_rect->y) + src_rect->x;
|
||||||
|
src = (uint32_t) src8;
|
||||||
|
|
||||||
|
#if __DCACHE_PRESENT
|
||||||
|
uint8_t *src8_tmp = src8;
|
||||||
|
for (int i = 0; i < src_rect->h; i++) {
|
||||||
|
SCB_CleanDCache_by_Addr(src8_tmp, src_rect->w);
|
||||||
|
src8_tmp += src_img->w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
uint16_t *src16 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, src_rect->y) + src_rect->x;
|
||||||
|
src = (uint32_t) src16;
|
||||||
|
|
||||||
|
#if __DCACHE_PRESENT
|
||||||
|
uint16_t *src16_tmp = src16;
|
||||||
|
for (int i = 0; i < src_rect->h; i++) {
|
||||||
|
SCB_CleanDCache_by_Addr(src16_tmp, src_rect->w * sizeof(uint16_t));
|
||||||
|
src16_tmp += src_img->w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t dst = (uint32_t) dst16;
|
||||||
|
|
||||||
|
#if defined(MCU_SERIES_H7)
|
||||||
|
if (hint & IMAGE_HINT_BLACK_BACKGROUND) {
|
||||||
|
dst = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HAL_DMA2D_BlendingStart(&dma2d, src, dst, (uint32_t) dst16, dst_rect->w, dst_rect->h);
|
||||||
|
HAL_DMA2D_PollForTransfer(&dma2d, 1000);
|
||||||
|
|
||||||
|
#if __DCACHE_PRESENT
|
||||||
|
// Ensures any cached reads to dst16 are dropped.
|
||||||
|
dst16_tmp = dst16;
|
||||||
|
for (int i = 0; i < dst_rect->h; i++) {
|
||||||
|
SCB_InvalidateDCache_by_Addr(dst16_tmp, dst_rect->w * sizeof(uint16_t));
|
||||||
|
dst16_tmp += dst_img->w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HAL_DMA2D_DeInit(&dma2d);
|
||||||
|
|
||||||
|
if (src_img->pixfmt == PIXFORMAT_GRAYSCALE) {
|
||||||
|
fb_free(); // clut
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (TIME_GPU == 1)
|
||||||
|
printf("draw time: %u ms\n", mp_hal_ticks_ms() - start);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // (OMV_GPU_ENABLE == 1)
|
||||||
@ -630,6 +630,7 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/ports/stm32/,\
|
|||||||
ulpi.o \
|
ulpi.o \
|
||||||
dma_utils.o \
|
dma_utils.o \
|
||||||
omv_gpio.o \
|
omv_gpio.o \
|
||||||
|
omv_gpu.o \
|
||||||
omv_i2c.o \
|
omv_i2c.o \
|
||||||
omv_spi.o \
|
omv_spi.o \
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user