summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Reufer <thomas@reufer.ch>2014-10-06 12:52:00 +0200
committerThomas Reufer <thomas@reufer.ch>2014-10-06 12:52:00 +0200
commit40033ad641925853ca993dca1db769d98a2aae51 (patch)
tree2d3cb780a3dab45862a32233ed2eb6bdba76d977
parent5249b7a1795e554ffab7e2fb7b5626d0f5eddf0e (diff)
downloadvdr-plugin-rpihddevice-40033ad641925853ca993dca1db769d98a2aae51.tar.gz
vdr-plugin-rpihddevice-40033ad641925853ca993dca1db769d98a2aae51.tar.bz2
move OVG OSD dispmanx handles back to OSD, introduce OSD reset command
-rw-r--r--display.c74
-rw-r--r--display.h10
-rw-r--r--ovgosd.c188
3 files changed, 126 insertions, 146 deletions
diff --git a/display.c b/display.c
index b82b6c8..95692ac 100644
--- a/display.c
+++ b/display.c
@@ -16,14 +16,6 @@ extern "C" {
cRpiDisplay* cRpiDisplay::s_instance = 0;
-class cRpiDisplay::cHandles
-{
-public:
-
- DISPMANX_DISPLAY_HANDLE_T display;
- DISPMANX_UPDATE_HANDLE_T update;
-};
-
cRpiDisplay* cRpiDisplay::GetInstance(void)
{
if (!s_instance)
@@ -69,28 +61,12 @@ cRpiDisplay::cRpiDisplay(int width, int height, int frameRate,
m_height(height),
m_frameRate(frameRate),
m_interlaced(false),
- m_port(port),
- m_handles(new cHandles())
+ m_port(port)
{
- m_handles->display = vc_dispmanx_display_open(
- m_port == cRpiVideoPort::eHDMI ? 0 : 1);
-
- if (m_handles->display)
- {
- m_handles->update = vc_dispmanx_update_start(0);
- if (m_handles->update == DISPMANX_NO_HANDLE)
- ELOG("failed to start display update!");
- }
- else
- ELOG("failed to open display!");
}
cRpiDisplay::~cRpiDisplay()
{
- if (m_handles->display)
- vc_dispmanx_display_close(m_handles->display);
-
- delete m_handles;
}
int cRpiDisplay::GetSize(int &width, int &height)
@@ -159,48 +135,30 @@ bool cRpiDisplay::IsProgressive(void)
return false;
}
-int cRpiDisplay::AddElement(DISPMANX_ELEMENT_HANDLE_T &element,
- int width, int height, int layer)
+int cRpiDisplay::Snapshot(unsigned char* frame, int width, int height)
{
cRpiDisplay* instance = GetInstance();
if (instance)
{
- VC_RECT_T dstRect = { 0, 0, width, height };
- VC_RECT_T srcRect = { 0, 0, width << 16, height << 16 };
-
- element = vc_dispmanx_element_add(instance->m_handles->update,
- instance->m_handles->display, layer, &dstRect, 0, &srcRect,
- DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T)0);
+ DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(
+ instance->m_port == cRpiVideoPort::eHDMI ? 0 : 1);
- if (!element)
+ if (display)
{
- ELOG("failed to add display element!");
- return -1;
- }
+ uint32_t image;
+ DISPMANX_RESOURCE_HANDLE_T res = vc_dispmanx_resource_create(
+ VC_IMAGE_RGB888, width, height, &image);
- vc_dispmanx_update_submit_sync(instance->m_handles->update);
- return 0;
- }
- return -1;
-}
-
-int cRpiDisplay::Snapshot(uint8_t* frame, int width, int height)
-{
- cRpiDisplay* instance = GetInstance();
- if (instance)
- {
- uint32_t image;
- DISPMANX_RESOURCE_HANDLE_T res = vc_dispmanx_resource_create(
- VC_IMAGE_RGB888, width, height, &image);
+ vc_dispmanx_snapshot(display, res,
+ (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_PACK));
- vc_dispmanx_snapshot(instance->m_handles->display, res,
- (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_PACK));
+ VC_RECT_T rect = { 0, 0, width, height };
+ vc_dispmanx_resource_read_data(res, &rect, frame, width * 3);
- VC_RECT_T rect = { 0, 0, width, height };
- vc_dispmanx_resource_read_data(res, &rect, frame, width * 3);
-
- vc_dispmanx_resource_delete(res);
- return 0;
+ vc_dispmanx_resource_delete(res);
+ vc_dispmanx_display_close(display);
+ return 0;
+ }
}
return -1;
}
diff --git a/display.h b/display.h
index 55a0780..f70abc4 100644
--- a/display.h
+++ b/display.h
@@ -9,10 +9,6 @@
#include "tools.h"
-extern "C" {
-#include "interface/vmcs_host/vc_dispmanx_types.h"
-}
-
class cRpiDisplay
{
@@ -30,9 +26,7 @@ public:
static int Get(int &width, int &height, int &frameRate, bool &interlaced);
static int Set(int width, int height, int frameRate, bool interlaced);
- static int AddElement(DISPMANX_ELEMENT_HANDLE_T &element,
- int width, int height, int layer);
- static int Snapshot(uint8_t* frame, int width, int height);
+ static int Snapshot(unsigned char* frame, int width, int height);
protected:
@@ -57,8 +51,6 @@ private:
cRpiDisplay(const cRpiDisplay&);
cRpiDisplay& operator= (const cRpiDisplay&);
- class cHandles;
- cHandles *m_handles;
};
class cRpiHDMIDisplay : public cRpiDisplay
diff --git a/ovgosd.c b/ovgosd.c
index 812b16d..6d316d0 100644
--- a/ovgosd.c
+++ b/ovgosd.c
@@ -45,7 +45,20 @@ public:
cOvgCmd() { }
virtual ~cOvgCmd() { }
- virtual void Execute(VGImage image, int width, int height) = 0;
+ virtual bool Execute(VGImage image, int width, int height) = 0;
+};
+
+class cOvgReset : public cOvgCmd
+{
+public:
+
+ cOvgReset() : cOvgCmd() { }
+ ~cOvgReset() { }
+
+ virtual bool Execute(VGImage image, int width, int height)
+ {
+ return false;
+ }
};
class cOvgClear : public cOvgCmd
@@ -55,10 +68,11 @@ public:
cOvgClear() : cOvgCmd() { }
~cOvgClear() { }
- virtual void Execute(VGImage image, int width, int height)
+ virtual bool Execute(VGImage image, int width, int height)
{
vgClearImage(image, 0, 0, width, height);
vgDrawImage(image);
+ return true;
}
};
@@ -80,11 +94,12 @@ public:
free(m_argb);
}
- virtual void Execute(VGImage image, int width, int height)
+ virtual bool Execute(VGImage image, int width, int height)
{
vgClearImage(image, m_x, m_y, m_w, m_h);
vgImageSubData(image, m_argb, m_d, VG_sARGB_8888, m_x, m_y, m_w, m_h);
vgDrawImage(image);
+ return true;
}
protected:
@@ -112,7 +127,7 @@ public:
delete m_pixmap;
}
- virtual void Execute(VGImage image, int width, int height)
+ virtual bool Execute(VGImage image, int width, int height)
{
int x = m_x + m_pixmap->ViewPort().X();
int y = m_y + m_pixmap->ViewPort().Y();
@@ -123,6 +138,7 @@ public:
vgClearImage(image, x, y, w, h);
vgImageSubData(image, m_pixmap->Data(), d, VG_sARGB_8888, x, y, w, h);
vgDrawImage(image);
+ return true;
}
protected:
@@ -139,29 +155,20 @@ class cOvg : public cThread
public:
cOvg() :
- cThread(),
- m_width(0),
- m_height(0),
- m_aspect(0)
+ cThread()
{
- cRpiDisplay::GetSize(m_width, m_height, m_aspect);
Start();
}
~cOvg()
{
Cancel(-1);
+ DoCmd(new cOvgReset());
+
while (Active())
cCondWait::SleepMs(50);
}
- void GetDisplaySize(int &width, int &height, double &aspect)
- {
- width = m_width;
- height = m_height;
- aspect = m_aspect;
- }
-
void DoCmd(cOvgCmd* cmd)
{
Lock();
@@ -175,11 +182,11 @@ protected:
{
DLOG("cOvg() thread started");
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (display == EGL_NO_DISPLAY)
+ EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (eglDisplay == EGL_NO_DISPLAY)
ELOG("failed to get EGL display connection!");
- if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ if (eglInitialize(eglDisplay, NULL, NULL) == EGL_FALSE)
ELOG("failed to init EGL display connection!");
eglBindAPI(EGL_OPENVG_API);
@@ -198,94 +205,116 @@ protected:
EGLint nConfig;
// get an appropriate EGL frame buffer configuration
- if (eglChooseConfig(display, attr, &config, 1, &nConfig) == EGL_FALSE)
+ if (eglChooseConfig(eglDisplay, attr, &config, 1, &nConfig)
+ == EGL_FALSE)
ELOG("failed to get EGL frame buffer config!");
// create an EGL rendering context
- EGLContext context = eglCreateContext(display, config, NULL, NULL);
+ EGLContext context = eglCreateContext(eglDisplay, config, NULL, NULL);
if (context == EGL_NO_CONTEXT)
ELOG("failed to create EGL rendering context!");
- DISPMANX_ELEMENT_HANDLE_T dispmanElement;
- cRpiDisplay::AddElement(dispmanElement, m_width, m_height, 2);
+ while (Running())
+ {
+ bool reset = false;
+
+ DISPMANX_DISPLAY_HANDLE_T dDisplay = vc_dispmanx_display_open(
+ cRpiDisplay::GetVideoPort() == cRpiVideoPort::eHDMI ? 0 : 1);
+ DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
- EGL_DISPMANX_WINDOW_T nativewindow;
- nativewindow.element = dispmanElement;
- nativewindow.width = m_width;
- nativewindow.height = m_height;
+ int width, height;
+ cRpiDisplay::GetSize(width, height);
- const EGLint windowAttr[] = {
- EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER,
- EGL_NONE
- };
+ VC_RECT_T dstRect = { 0, 0, width, height };
+ VC_RECT_T srcRect = { 0, 0, width << 16, height << 16 };
- EGLSurface surface = eglCreateWindowSurface(display, config,
- &nativewindow, windowAttr);
- if (surface == EGL_NO_SURFACE)
- ELOG("failed to create EGL window surface!");
+ DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(
+ update, dDisplay, 2 /*layer*/, &dstRect, 0, &srcRect,
+ DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T)0);
+ vc_dispmanx_update_submit_sync(update);
- // connect the context to the surface
- if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
- ELOG("failed to connect context to surface!");
+ EGL_DISPMANX_WINDOW_T nativewindow;
+ nativewindow.element = element;
+ nativewindow.width = width;
+ nativewindow.height = height;
- float color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- vgSetfv(VG_CLEAR_COLOR, 4, color);
- vgClear(0, 0, m_width, m_height);
- eglSwapBuffers(display, surface);
+ const EGLint windowAttr[] = {
+ EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER,
+ EGL_NONE
+ };
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
- vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
- vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+ EGLSurface surface = eglCreateWindowSurface(eglDisplay, config,
+ &nativewindow, windowAttr);
+ if (surface == EGL_NO_SURFACE)
+ ELOG("failed to create EGL window surface!");
- vgLoadIdentity();
- vgScale(1.0f, -1.0f);
- vgTranslate(0.0f, -m_height);
+ // connect the context to the surface
+ if (eglMakeCurrent(eglDisplay, surface, surface, context)
+ == EGL_FALSE)
+ ELOG("failed to connect context to surface!");
- VGImage image = vgCreateImage(VG_sARGB_8888, m_width, m_height,
- VG_IMAGE_QUALITY_BETTER);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ vgSetfv(VG_CLEAR_COLOR, 4, color);
+ vgClear(0, 0, width, height);
+ eglSwapBuffers(eglDisplay, surface);
- while (Running())
- {
- while (!m_commands.empty())
- {
- Lock();
- cOvgCmd* cmd = m_commands.front();
- m_commands.pop();
- Unlock();
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+
+ vgLoadIdentity();
+ vgScale(1.0f, -1.0f);
+ vgTranslate(0.0f, -height);
- if (cmd)
+ VGImage image = vgCreateImage(VG_sARGB_8888, width, height,
+ VG_IMAGE_QUALITY_BETTER);
+
+ while (!reset)
+ {
+ while (!m_commands.empty())
{
- cmd->Execute(image, m_width, m_height);
- eglSwapBuffers(display, surface);
- delete cmd;
+ Lock();
+ cOvgCmd* cmd = m_commands.front();
+ m_commands.pop();
+ Unlock();
+
+ if (cmd)
+ {
+ if (cmd->Execute(image, width, height))
+ eglSwapBuffers(eglDisplay, surface);
+ else
+ reset = true;
+ delete cmd;
+ }
}
+ if (!reset)
+ cCondWait::SleepMs(10);
}
- cCondWait::SleepMs(10);
- }
- vgDestroyImage(image);
+ vgDestroyImage(image);
- // clear screen
- glClear(GL_COLOR_BUFFER_BIT);
- eglSwapBuffers(display, surface);
+ // clear screen
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(eglDisplay, surface);
- // Release OpenGL resources
- eglMakeCurrent(display,
- EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroySurface(display, surface);
- eglDestroyContext(display, context);
- eglTerminate(display);
+ // Release OpenGL resources
+ eglMakeCurrent(eglDisplay,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(eglDisplay, surface);
+
+ vc_dispmanx_element_remove(update, element);
+ vc_dispmanx_display_close(dDisplay);
+ }
+
+ eglDestroyContext(eglDisplay, context);
+ eglTerminate(eglDisplay);
DLOG("cOvg() thread ended");
}
private:
- int m_width;
- int m_height;
- double m_aspect;
-
std::queue<cOvgCmd*> m_commands;
};
@@ -316,6 +345,7 @@ cOvgOsd::cOvgOsd(int Left, int Top, uint Level, cOvg *ovg) :
cOsd(Left, Top, Level),
m_ovg(ovg)
{
+ m_ovg->DoCmd(new cOvgReset());
}
cOvgOsd::~cOvgOsd()