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