Skip to content

Commit 289619c

Browse files
committed
openglosd: Implement cPixmap::Copy() and cPixmap::Render()
This fixes an issue with remaining OSD parts of a confirm message in VDR skins.
1 parent b9464a1 commit 289619c

2 files changed

Lines changed: 127 additions & 3 deletions

File tree

openglosd.cpp

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,60 @@ bool cOglCmdCopyBufferToOutputFb::Execute(void)
10281028
return true;
10291029
}
10301030

1031+
//------------------ cOglCmdRenderFbToFb ------------------------
1032+
bool cOglCmdRenderFbToFb::Execute(void) {
1033+
if (!m_pFramebuffer || !m_pSrcFb || m_srcRect.IsEmpty() || m_pFramebuffer == m_pSrcFb)
1034+
return false;
1035+
1036+
GLfloat x1 = m_dstPoint.X();
1037+
GLfloat y1 = m_dstPoint.Y();
1038+
GLfloat x2 = x1 + m_srcRect.Width();
1039+
GLfloat y2 = y1 + m_srcRect.Height();
1040+
1041+
GLfloat texX1 = (GLfloat) m_srcRect.X() / (GLfloat)m_pSrcFb->Width();
1042+
GLfloat texX2 = (GLfloat)(m_srcRect.X() + m_srcRect.Width()) / (GLfloat)m_pSrcFb->Width();
1043+
GLfloat texY1 = (GLfloat)(m_pSrcFb->Height() - m_srcRect.Y() - 1) / (GLfloat)m_pSrcFb->Height();
1044+
GLfloat texY2 = (GLfloat)(m_pSrcFb->Height() - m_srcRect.Y() - m_srcRect.Height() - 1) / (GLfloat)m_pSrcFb->Height();
1045+
1046+
GLfloat quadVertices[] = {
1047+
// Position Texture
1048+
x1, y1, texX1, texY2,
1049+
x1, y2, texX1, texY1,
1050+
x2, y2, texX2, texY1,
1051+
1052+
x1, y1, texX1, texY2,
1053+
x2, y2, texX2, texY1,
1054+
x2, y1, texX2, texY2
1055+
};
1056+
1057+
VertexBuffers[vbTexture]->ActivateShader();
1058+
VertexBuffers[vbTexture]->SetShaderAlpha(m_alpha);
1059+
VertexBuffers[vbTexture]->SetShaderProjectionMatrix(m_pFramebuffer->Width(), m_pFramebuffer->Height());
1060+
VertexBuffers[vbTexture]->SetShaderBorderColor(clrTransparent);
1061+
1062+
m_pFramebuffer->Bind();
1063+
1064+
if (!m_pSrcFb->BindTexture()) {
1065+
m_pFramebuffer->Unbind();
1066+
return false;
1067+
}
1068+
1069+
if (m_alpha == ALPHA_OPAQUE)
1070+
VertexBuffers[vbTexture]->DisableBlending();
1071+
1072+
VertexBuffers[vbTexture]->Bind();
1073+
VertexBuffers[vbTexture]->SetVertexSubData(quadVertices);
1074+
VertexBuffers[vbTexture]->DrawArrays();
1075+
VertexBuffers[vbTexture]->Unbind();
1076+
1077+
if (m_alpha == ALPHA_OPAQUE)
1078+
VertexBuffers[vbTexture]->EnableBlending();
1079+
1080+
m_pFramebuffer->Unbind();
1081+
1082+
return true;
1083+
}
1084+
10311085
//------------------ cOglCmdFill ----------------------------
10321086
bool cOglCmdFill::Execute(void)
10331087
{
@@ -2297,12 +2351,58 @@ void cOglPixmap::DrawSlope(const cRect &rect, tColor color, int type)
22972351

22982352
void cOglPixmap::Render(const cPixmap *pixmap, const cRect &source, const cPoint &dest)
22992353
{
2300-
LOGWARNING("openglosd: %s: %d %d %d not implemented in OpenGl OSD", __FUNCTION__, pixmap->ViewPort().X(), source.X(), dest.X());
2354+
RenderPixmapInternal(pixmap, source, dest, true);
23012355
}
23022356

23032357
void cOglPixmap::Copy(const cPixmap *pixmap, const cRect &source, const cPoint &dest)
23042358
{
2305-
LOGWARNING("openglosd: %s: %d %d %d not implemented in OpenGl OSD", __FUNCTION__, pixmap->ViewPort().X(), source.X(), dest.X());
2359+
// render without respect to alpha values
2360+
RenderPixmapInternal(pixmap, source, dest, false);
2361+
}
2362+
2363+
void cOglPixmap::RenderPixmapInternal(const cPixmap *pixmap, const cRect &source, const cPoint &dest, bool useAlpha)
2364+
{
2365+
LOGDEBUG2(L_OPENGL, "openglosd: %s: %s", __FUNCTION__, useAlpha ? "Render()" : "Copy()");
2366+
2367+
if (!m_pOglThread->Active() || !pixmap || source.IsEmpty())
2368+
return;
2369+
2370+
LOCK_PIXMAPS;
2371+
2372+
const cOglPixmap *sourceOgl = dynamic_cast<const cOglPixmap *>(pixmap);
2373+
2374+
// Self-rendering is not allowed according to VDR API
2375+
if (sourceOgl && sourceOgl != this) {
2376+
cRect sourceRect = source.Intersected(cRect(0, 0, sourceOgl->DrawPort().Width(), sourceOgl->DrawPort().Height()));
2377+
sourceRect.SetX(sourceRect.X() + sourceOgl->DrawPort().X());
2378+
sourceRect.SetY(sourceRect.Y() + sourceOgl->DrawPort().Y());
2379+
2380+
cRect destRect(dest, sourceRect.Size());
2381+
cRect clippedDest = destRect.Intersected(cRect(0, 0, m_pFramebuffer->Width(), m_pFramebuffer->Height()));
2382+
if (clippedDest.IsEmpty())
2383+
return;
2384+
2385+
sourceRect.SetX(sourceRect.X() + clippedDest.X() - destRect.X());
2386+
sourceRect.SetY(sourceRect.Y() + clippedDest.Y() - destRect.Y());
2387+
sourceRect.SetWidth(clippedDest.Width());
2388+
sourceRect.SetHeight(clippedDest.Height());
2389+
if (sourceRect.IsEmpty())
2390+
return;
2391+
2392+
m_pOglThread->DoCmd(new cOglCmdRenderFbToFb(m_pFramebuffer,
2393+
sourceOgl->Framebuffer(),
2394+
sourceRect,
2395+
clippedDest.Point(),
2396+
useAlpha ? sourceOgl->Alpha() : ALPHA_OPAQUE));
2397+
2398+
SetDirty();
2399+
MarkDrawPortDirty(cRect(clippedDest.X(), clippedDest.Y(), sourceRect.Width(), sourceRect.Height()));
2400+
2401+
return;
2402+
}
2403+
2404+
if (!sourceOgl)
2405+
LOGWARNING("openglosd: %s: %s is not implemented in OpenGl OSD for your VDR version", __FUNCTION__, useAlpha ? "Render()" : "Copy()");
23062406
}
23072407

23082408
void cOglPixmap::Scroll(const cPoint &dest, const cRect &source)

openglosd.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,29 @@ class cOglCmdCopyBufferToOutputFb : public cOglCmd {
460460
cSoftHdDevice *m_pDevice;
461461
};
462462

463+
/**
464+
* OpenGL command: Render a framebuffer into another one
465+
*
466+
* @ingroup osd
467+
*/
468+
class cOglCmdRenderFbToFb : public cOglCmd {
469+
public:
470+
cOglCmdRenderFbToFb(cOglFb *dstFb, cOglFb *srcFb, const cRect &src, const cPoint &dst, int alpha)
471+
: cOglCmd(dstFb),
472+
m_pSrcFb(srcFb),
473+
m_srcRect(src),
474+
m_dstPoint(dst),
475+
m_alpha(alpha) {};
476+
virtual ~cOglCmdRenderFbToFb(void) {};
477+
virtual const char* Description(void) { return "Render framebuffer"; }
478+
virtual bool Execute(void);
479+
private:
480+
cOglFb *m_pSrcFb;
481+
cRect m_srcRect;
482+
cPoint m_dstPoint;
483+
int m_alpha;
484+
};
485+
463486
/**
464487
* OpenGL command: Fill a polygon
465488
*
@@ -760,7 +783,7 @@ class cOglPixmap : public cPixmap {
760783
cOglPixmap(std::shared_ptr<cOglThread>, int, const cRect &, const cRect &DrawPort = cRect::Null);
761784
virtual ~cOglPixmap(void);
762785

763-
cOglFb *Framebuffer(void) { return m_pFramebuffer; };
786+
cOglFb *Framebuffer(void) const { return m_pFramebuffer; };
764787
int X(void) { return ViewPort().X(); };
765788
int Y(void) { return ViewPort().Y(); };
766789
virtual bool IsDirty(void) { return m_dirty; }
@@ -799,6 +822,7 @@ class cOglPixmap : public cPixmap {
799822
void DrawGridText(const cPoint &, const char *, tColor, tColor, const cFont *, int Width = 0, int Height = 0, int Alignment = taDefault);
800823
#endif
801824
void DrawTextInternal(const cPoint &, const char *, tColor, tColor, const cFont *, int Width = 0, int Height = 0, int Alignment = taDefault, bool isGridText = false);
825+
void RenderPixmapInternal(const cPixmap *, const cRect &, const cPoint &, bool);
802826
};
803827

804828
/**

0 commit comments

Comments
 (0)