diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am
index e7d4eaf43..37040c4b0 100644
--- a/src/driver/Makefile.am
+++ b/src/driver/Makefile.am
@@ -47,6 +47,8 @@ libneutrino_driver_a_SOURCES = \
volume.cpp
if BOXTYPE_COOL
+libneutrino_driver_a_SOURCES += \
+ fb_accel_cs_hdx.cpp
if BOXMODEL_CS_HD2
libneutrino_driver_a_SOURCES += \
fb_accel_cs_hd2.cpp \
diff --git a/src/driver/fb_accel.h b/src/driver/fb_accel.h
index 84e42ffe1..6343056f9 100644
--- a/src/driver/fb_accel.h
+++ b/src/driver/fb_accel.h
@@ -78,17 +78,41 @@ class CFbAccelSTi
void setBlendLevel(int);
};
-class CFbAccelCSHD1
+class CFbAccelCSHDx
: public CFbAccel
{
private:
+
+ protected:
+ OpenThreads::Mutex mutex;
+
+ int fbCopy(uint32_t *mem_p, int width, int height, int dst_x, int dst_y, int src_x, int src_y, int mode);
+ int fbFill(int sx, int sy, int width, int height, fb_pixel_t color, int mode=0);
+
+ public:
+ CFbAccelCSHDx();
+// ~CFbAccelCSHDx();
+
+#if 0
+ /* TODO: Run this functions with hardware acceleration */
+ void SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp);
+ void RestoreScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp);
+ void Clear();
+#endif
+};
+
+class CFbAccelCSHD1
+ : public CFbAccelCSHDx
+{
+ private:
fb_pixel_t lastcol;
+ fb_pixel_t *backbuffer;
int devmem_fd; /* to access the GXA register we use /dev/mem */
unsigned int smem_start; /* as aquired from the fbdev, the framebuffers physical start address */
volatile uint8_t *gxa_base; /* base address for the GXA's register access */
+
void setColor(fb_pixel_t col);
- void run(void);
- fb_pixel_t *backbuffer;
+
public:
CFbAccelCSHD1();
~CFbAccelCSHD1();
@@ -113,10 +137,12 @@ class CFbAccelCSHD1
};
class CFbAccelCSHD2
- : public CFbAccel
+ : public CFbAccelCSHDx
{
private:
fb_pixel_t *backbuffer;
+ int sysRev;
+ bool IsApollo;
public:
CFbAccelCSHD2();
diff --git a/src/driver/fb_accel_cs_hd1.cpp b/src/driver/fb_accel_cs_hd1.cpp
index 2d4f4ad2a..2b6b0e0dd 100644
--- a/src/driver/fb_accel_cs_hd1.cpp
+++ b/src/driver/fb_accel_cs_hd1.cpp
@@ -264,13 +264,21 @@ void CFbAccelCSHD1::paintBoxRel(const int x, const int y, const int dx, const in
void CFbAccelCSHD1::fbCopyArea(uint32_t width, uint32_t height, uint32_t dst_x, uint32_t dst_y, uint32_t src_x, uint32_t src_y)
{
+ if ((width == 0) || (height == 0))
+ return;
+
uint32_t w_, h_;
w_ = (width > xRes) ? xRes : width;
h_ = (height > yRes) ? yRes : height;
- //printf("\033[33m>>>>\033[0m [CFbAccelCSHD1::%s:%d] fb_copyarea w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func__, __LINE__, w_, h_, dst_x, dst_y, src_x, src_y);
- printf("\033[31m>>>>\033[0m [CFbAccelCSHD1::%s:%d] sw blit w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func__, __LINE__, w_, h_, dst_x, dst_y, src_x, src_y);
- CFrameBuffer::fbCopyArea(width, height, dst_x, dst_y, src_x, src_y);
+ int mode = CS_FBCOPY_FB2FB;
+ uint32_t src_y_ = src_y;
+ if (src_y >= yRes) {
+ mode = CS_FBCOPY_BB2FB;
+ src_y_ -= yRes;
+ }
+ fbCopy(NULL, w_, h_, dst_x, dst_y, src_x, src_y_, mode);
+// printf("\033[31m>>>>\033[0m%s hw blit w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func_ext__, w_, h_, dst_x, dst_y, src_x, src_y);
}
void CFbAccelCSHD1::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
diff --git a/src/driver/fb_accel_cs_hd2.cpp b/src/driver/fb_accel_cs_hd2.cpp
index 36a99ca0e..cfafaf4bf 100644
--- a/src/driver/fb_accel_cs_hd2.cpp
+++ b/src/driver/fb_accel_cs_hd2.cpp
@@ -28,7 +28,9 @@
CFbAccelCSHD2::CFbAccelCSHD2()
{
- fb_name = "Coolstream HD2 framebuffer";
+ fb_name = "Coolstream HD2 framebuffer";
+ IsApollo = false;
+ sysRev = -1;
}
/*
@@ -143,11 +145,22 @@ void CFbAccelCSHD2::paintBoxRel(const int x, const int y, const int dx, const in
void CFbAccelCSHD2::fbCopyArea(uint32_t width, uint32_t height, uint32_t dst_x, uint32_t dst_y, uint32_t src_x, uint32_t src_y)
{
+ if ((width == 0) || (height == 0))
+ return;
+
uint32_t w_, h_;
w_ = (width > xRes) ? xRes : width;
h_ = (height > yRes) ? yRes : height;
- if(!(w_%4)) {
+ if (sysRev < 0) {
+ sysRev = cs_get_revision();
+ IsApollo = (sysRev == 9);
+ }
+
+ if(!(w_ % 4) && !IsApollo) {
+ /* workaround for bad fb driver */
+ w_ -= 1;
+ h_ -= 1;
fb_copyarea area;
area.dx = dst_x;
area.dy = dst_y;
@@ -156,11 +169,18 @@ void CFbAccelCSHD2::fbCopyArea(uint32_t width, uint32_t height, uint32_t dst_x,
area.sx = src_x;
area.sy = src_y;
ioctl(fd, FBIO_COPY_AREA, &area);
- //printf("\033[33m>>>>\033[0m [CFbAccelCSHD2::%s:%d] fb_copyarea w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func__, __LINE__, w_, h_, dst_x, dst_y, src_x, src_y);
- return;
+// printf("\033[33m>>>>\033[0m%s fb_copyarea w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func_ext__, w_, h_, dst_x, dst_y, src_x, src_y);
+ }
+ else {
+ int mode = CS_FBCOPY_FB2FB;
+ uint32_t src_y_ = src_y;
+ if (src_y >= yRes) {
+ mode = CS_FBCOPY_BB2FB;
+ src_y_ -= yRes;
+ }
+ fbCopy(NULL, w_, h_, dst_x, dst_y, src_x, src_y_, mode);
+// printf("\033[31m>>>>\033[0m%s fbCopy w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func_ext__, w_, h_, dst_x, dst_y, src_x, src_y);
}
- //printf("\033[31m>>>>\033[0m [CFbAccelCSHD2::%s:%d] sw blit w: %d, h: %d, dst_x: %d, dst_y: %d, src_x: %d, src_y: %d\n", __func__, __LINE__, w_, h_, dst_x, dst_y, src_x, src_y);
- CFrameBuffer::fbCopyArea(width, height, dst_x, dst_y, src_x, src_y);
}
void CFbAccelCSHD2::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
diff --git a/src/driver/fb_accel_cs_hdx.cpp b/src/driver/fb_accel_cs_hdx.cpp
new file mode 100644
index 000000000..3ab238f35
--- /dev/null
+++ b/src/driver/fb_accel_cs_hdx.cpp
@@ -0,0 +1,122 @@
+/*
+ Framebuffer acceleration hardware abstraction functions.
+ The common functions for coolstream hd1/hd2 graphic chips
+ are represented in this class.
+
+ (C) 2017 M. Liebmann
+
+ License: GPL
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "fb_accel_cs_hdx_inc.h"
+
+#define LOGTAG "[fb_accel_cs_hdx] "
+
+CFbAccelCSHDx::CFbAccelCSHDx()
+{
+ fb_name = "CST HDx framebuffer";
+}
+
+/*
+CFbAccelCSHDx::~CFbAccelCSHDx()
+{
+}
+*/
+
+int CFbAccelCSHDx::fbCopy(uint32_t *mem_p, int width, int height,
+ int dst_x, int dst_y, int src_x, int src_y, int mode)
+{
+ if (videoDecoder == NULL) {
+ if (dst_y < (int)yRes) {
+ uint32_t src_y_ = src_y;
+ if (mode == CS_FBCOPY_BB2FB)
+ src_y_ += yRes;
+ CFrameBuffer::fbCopyArea(width, height, dst_x, dst_y, src_x, src_y_);
+ return 0;
+ }
+ return -1;
+ }
+
+ mutex.lock();
+ setActive(false);
+ int ret = videoDecoder->fbCopy(mem_p, width, height, dst_x, dst_y, src_x, src_y, mode);
+ add_gxa_sync_marker();
+ setActive(true);
+ mutex.unlock();
+ return ret;
+}
+
+int CFbAccelCSHDx::fbFill(int sx, int sy, int width, int height, fb_pixel_t color, int mode/*=0*/)
+{
+ if (videoDecoder == NULL) {
+ CFbAccel::paintRect(sx, sy, width, height, color);
+ return 0;
+ }
+
+ mutex.lock();
+ setActive(false);
+ int ret = videoDecoder->fbFill(sx, sy, width, height, color, mode);
+ add_gxa_sync_marker();
+ setActive(true);
+ mutex.unlock();
+ return ret;
+}
+
+#if 0
+/* TODO: Run this functions with hardware acceleration */
+void CFbAccelCSHDx::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp)
+{
+ if (!getActive())
+ return;
+
+ checkFbArea(x, y, dx, dy, true);
+ fb_pixel_t * pos = getFrameBufferPointer() + x + swidth * y;
+ fb_pixel_t * bkpos = memp;
+ for (int count = 0; count < dy; count++) {
+ fb_pixel_t * dest = (fb_pixel_t *)pos;
+ for (int i = 0; i < dx; i++)
+ *(bkpos++) = *(dest++);
+ pos += swidth;
+ }
+ checkFbArea(x, y, dx, dy, false);
+printf("%s\n", __func_ext__);
+}
+
+void CFbAccelCSHDx::RestoreScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp)
+{
+ if (!getActive())
+ return;
+
+ checkFbArea(x, y, dx, dy, true);
+ fb_pixel_t * fbpos = getFrameBufferPointer() + x + swidth * y;
+ fb_pixel_t * bkpos = memp;
+ for (int count = 0; count < dy; count++)
+ {
+ memmove(fbpos, bkpos, dx * sizeof(fb_pixel_t));
+ fbpos += swidth;
+ bkpos += dx;
+ }
+ mark(x, y, x + dx, y + dy);
+ checkFbArea(x, y, dx, dy, false);
+printf("%s\n", __func_ext__);
+}
+
+void CFbAccelCSHDx::Clear()
+{
+ paintBackground();
+printf("%s\n", __func_ext__);
+}
+#endif
diff --git a/src/driver/fb_accel_cs_hdx_inc.h b/src/driver/fb_accel_cs_hdx_inc.h
index 5135e953d..5f98cd34b 100644
--- a/src/driver/fb_accel_cs_hdx_inc.h
+++ b/src/driver/fb_accel_cs_hdx_inc.h
@@ -1,6 +1,6 @@
/*
Framebuffer acceleration hardware abstraction functions.
- The hardware dependent acceleration functions for coolstream hdx graphic chips
+ The common functions for coolstream hd1/hd2 graphic chips
are represented in this class.
(C) 2017 M. Liebmann
@@ -23,6 +23,8 @@
along with this program. If not, see .
*/
+#ifndef FB_ACCEL_CS_HDX_INC_H
+#define FB_ACCEL_CS_HDX_INC_H
#include
#include
@@ -31,12 +33,16 @@
#include
#include
#include
+#include
+
#include
#include
#include
-
#include
#include
+#include
#include
extern cVideo * videoDecoder;
+
+#endif // FB_ACCEL_CS_HDX_INC_H