Use DMA ops for blending in drawFilledRect()
This commit is contained in:
+22
-2
@@ -201,8 +201,28 @@ void BitmapBuffer::drawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, ui
|
||||
if (!applyClippingRect(x, y, w, h))
|
||||
return;
|
||||
|
||||
for (coord_t i = y; i < y + h; i++) {
|
||||
drawHorizontalLineAbs(x, i, w, pat, flags, opacity);
|
||||
// Use DMA instead...
|
||||
if (SOLID != pat) {
|
||||
for (coord_t i = y; i < y + h; i++) {
|
||||
drawHorizontalLineAbs(x, i, w, pat, flags, opacity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// SOLID
|
||||
|
||||
// Use the DMA2D to blend a scratch buffer filled with overlay color
|
||||
BitmapBuffer scratch(BMP_ARGB4444, LCD_W, LCD_H, lcdGetScratchBuffer());
|
||||
RGB_SPLIT(COLOR_VAL(flags), r, g, b);
|
||||
|
||||
LcdFlags flags =
|
||||
uint32_t(ARGB((OPACITY_MAX - opacity) << 4, r << 3, g << 2, b << 3))
|
||||
<< 16;
|
||||
|
||||
// Fill the buffer
|
||||
scratch.drawSolidFilledRect(0, 0, w, h, flags);
|
||||
|
||||
// And blend
|
||||
drawBitmapAbs(x, y, &scratch, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+64
-58
@@ -394,6 +394,70 @@ class BitmapBuffer: public BitmapBufferBase<pixel_t>
|
||||
if (x >= xmax || y >= ymax)
|
||||
return;
|
||||
|
||||
drawBitmapAbs<T>(x, y, bmp, srcx, srcy, srcw, srch, scale);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void drawScaledBitmap(const T * bitmap, coord_t x, coord_t y, coord_t w, coord_t h)
|
||||
{
|
||||
if (bitmap) {
|
||||
float vscale = float(h) / bitmap->height();
|
||||
float hscale = float(w) / bitmap->width();
|
||||
float scale = vscale < hscale ? vscale : hscale;
|
||||
|
||||
int xshift = (w - (bitmap->width() * scale)) / 2;
|
||||
int yshift = (h - (bitmap->height() * scale)) / 2;
|
||||
drawBitmap(x + xshift, y + yshift, bitmap, 0, 0, 0, 0, scale);
|
||||
}
|
||||
}
|
||||
|
||||
BitmapBuffer * horizontalFlip() const;
|
||||
|
||||
BitmapBuffer * verticalFlip() const;
|
||||
|
||||
BitmapBuffer * invertMask() const;
|
||||
|
||||
protected:
|
||||
static BitmapBuffer * load_bmp(const char * filename);
|
||||
static BitmapBuffer * load_stb(const char * filename);
|
||||
|
||||
inline bool applyClippingRect(coord_t & x, coord_t & y, coord_t & w, coord_t & h) const
|
||||
{
|
||||
if (h < 0) {
|
||||
y += h;
|
||||
h = -h;
|
||||
}
|
||||
|
||||
if (w < 0) {
|
||||
x += w;
|
||||
w = -w;
|
||||
}
|
||||
|
||||
if (x >= xmax || y >= ymax)
|
||||
return false;
|
||||
|
||||
if (y < ymin) {
|
||||
h += y - ymin;
|
||||
y = ymin;
|
||||
}
|
||||
|
||||
if (x < xmin) {
|
||||
w += x - xmin;
|
||||
x = xmin;
|
||||
}
|
||||
|
||||
if (y + h > ymax)
|
||||
h = ymax - y;
|
||||
|
||||
if (x + w > xmax)
|
||||
w = xmax - x;
|
||||
|
||||
return data && h > 0 && w > 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void drawBitmapAbs(coord_t x, coord_t y, const T * bmp, coord_t srcx = 0, coord_t srcy = 0, coord_t srcw = 0, coord_t srch = 0, float scale = 0)
|
||||
{
|
||||
coord_t bmpw = bmp->width();
|
||||
coord_t bmph = bmp->height();
|
||||
|
||||
@@ -483,64 +547,6 @@ class BitmapBuffer: public BitmapBufferBase<pixel_t>
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void drawScaledBitmap(const T * bitmap, coord_t x, coord_t y, coord_t w, coord_t h)
|
||||
{
|
||||
if (bitmap) {
|
||||
float vscale = float(h) / bitmap->height();
|
||||
float hscale = float(w) / bitmap->width();
|
||||
float scale = vscale < hscale ? vscale : hscale;
|
||||
|
||||
int xshift = (w - (bitmap->width() * scale)) / 2;
|
||||
int yshift = (h - (bitmap->height() * scale)) / 2;
|
||||
drawBitmap(x + xshift, y + yshift, bitmap, 0, 0, 0, 0, scale);
|
||||
}
|
||||
}
|
||||
|
||||
BitmapBuffer * horizontalFlip() const;
|
||||
|
||||
BitmapBuffer * verticalFlip() const;
|
||||
|
||||
BitmapBuffer * invertMask() const;
|
||||
|
||||
protected:
|
||||
static BitmapBuffer * load_bmp(const char * filename);
|
||||
static BitmapBuffer * load_stb(const char * filename);
|
||||
|
||||
inline bool applyClippingRect(coord_t & x, coord_t & y, coord_t & w, coord_t & h) const
|
||||
{
|
||||
if (h < 0) {
|
||||
y += h;
|
||||
h = -h;
|
||||
}
|
||||
|
||||
if (w < 0) {
|
||||
x += w;
|
||||
w = -w;
|
||||
}
|
||||
|
||||
if (x >= xmax || y >= ymax)
|
||||
return false;
|
||||
|
||||
if (y < ymin) {
|
||||
h += y - ymin;
|
||||
y = ymin;
|
||||
}
|
||||
|
||||
if (x < xmin) {
|
||||
w += x - xmin;
|
||||
x = xmin;
|
||||
}
|
||||
|
||||
if (y + h > ymax)
|
||||
h = ymax - y;
|
||||
|
||||
if (x + w > xmax)
|
||||
w = xmax - x;
|
||||
|
||||
return data && h > 0 && w > 0;
|
||||
}
|
||||
|
||||
uint8_t drawChar(coord_t x, coord_t y, const uint8_t * font, const uint16_t * spec, unsigned int index, LcdFlags flags);
|
||||
|
||||
inline void drawPixel(pixel_t * p, pixel_t value)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "libopenui_config.h"
|
||||
|
||||
void lcdNextLayer();
|
||||
uint16_t* lcdGetScratchBuffer();
|
||||
void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
|
||||
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
|
||||
void onKeyPress();
|
||||
|
||||
Reference in New Issue
Block a user