cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory; a cPixmap with a negative layer no longer marks any portion of the OSD's view port as "dirty"; Added a missing initialization of "panning" to the constructor of cPixmapMemory

This commit is contained in:
Klaus Schmidinger 2015-02-11 09:48:02 +01:00
parent 89f5244007
commit 22106f6dd3
5 changed files with 81 additions and 31 deletions

View File

@ -3308,6 +3308,8 @@ Thomas Reufer <thomas@reufer.ch>
for adding cOsdProvider::OsdSizeChanged()
for suggesting to change the German translations if the texts related to "binary
skipping"
for suggesting to change the return value of cOsd::RenderPixmaps() from cPixmapMemory
to cPixmap
Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting

16
HISTORY
View File

@ -8523,7 +8523,7 @@ Video Disk Recorder Revision History
copy process has been successful (problem reported by Christoph Haubrich).
- Added the UPDATE-2.2.0 file.
2015-02-10: Version 2.1.10
2015-02-11: Version 2.1.10
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Updated the Macedonian OSD texts (thanks to Dimitar Petrovski).
@ -8551,3 +8551,17 @@ Video Disk Recorder Revision History
of using the environment variable VDR_CHARSET_OVERRIDE still works, but is now
deprecated and may be removed in a future version. The value given in the --chartab
option takes precedence over that in VDR_CHARSET_OVERRIDE.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
(suggested by Thomas Reufer). This is necessary to allow plugins with derived
cPixmap implementations to use this function. Plugins that use this function
with cPixmapMemory now need to add a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
The dvbhddevice plugin has been modified accordingly.
- A cPixmap with a negative layer no longer marks any portion of the OSD's view port
as "dirty" when drawing on it. This may improve performance when drawing on a
hidden pixmap, because it avoids unnecessary refreshes of the OSD.
- Added a missing initialization of "panning" to the constructor of cPixmapMemory.

View File

@ -127,6 +127,15 @@ Plugins:
- Added cOsdProvider::OsdSizeChanged(), which plugins that implement an output device
can call to signal a change in the OSD that requires a redraw of the currently
displayed object.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
This is necessary to allow plugins with derived cPixmap implementations to use this
function. Plugins that use this function with cPixmapMemory now need to add
a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
Skins:
@ -220,6 +229,15 @@ OSD:
is unexpected at this point. You can still navigate to
the last replayed recording (if any) by pressing Ok repeatedly in the Recordings
menu.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
This is necessary to allow plugins with derived cPixmap implementations to use this
function. Plugins that use this function with cPixmapMemory now need to add
a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
Channels:

62
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.c 3.4 2015/01/15 11:20:56 kls Exp $
* $Id: osd.c 3.5 2015/02/11 09:48:02 kls Exp $
*/
#include "osd.h"
@ -984,12 +984,13 @@ cPixmap::cPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort)
void cPixmap::MarkViewPortDirty(const cRect &Rect)
{
dirtyViewPort.Combine(Rect.Intersected(viewPort));
if (layer >= 0)
dirtyViewPort.Combine(Rect.Intersected(viewPort));
}
void cPixmap::MarkViewPortDirty(const cPoint &Point)
{
if (viewPort.Contains(Point))
if (layer >= 0 && viewPort.Contains(Point))
dirtyViewPort.Combine(Point);
}
@ -1025,11 +1026,18 @@ void cPixmap::SetLayer(int Layer)
esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1);
Layer = MAXPIXMAPLAYERS - 1;
}
if (Layer != layer) {
if (Layer > 0 || layer > 0)
MarkViewPortDirty(viewPort);
// The sequence here is important, because the view port is only marked as dirty
// if the layer is >= 0:
if (layer >= 0) {
MarkViewPortDirty(viewPort); // the pixmap is visible and may or may not become invisible
layer = Layer;
}
else if (Layer >= 0) {
layer = Layer;
MarkViewPortDirty(viewPort); // the pixmap was invisible and has become visible
}
else
layer = Layer; // the pixmap was invisible and remains so
Unlock();
}
@ -1141,6 +1149,7 @@ cPixmapMemory::cPixmapMemory(int Layer, const cRect &ViewPort, const cRect &Draw
:cPixmap(Layer, ViewPort, DrawPort)
{
data = MALLOC(tColor, this->DrawPort().Width() * this->DrawPort().Height());
panning = false;
}
cPixmapMemory::~cPixmapMemory()
@ -1714,7 +1723,8 @@ void cOsd::DestroyPixmap(cPixmap *Pixmap)
LOCK_PIXMAPS;
for (int i = 1; i < pixmaps.Size(); i++) { // begin at 1 - don't let the background pixmap be destroyed!
if (pixmaps[i] == Pixmap) {
pixmaps[0]->MarkViewPortDirty(Pixmap->ViewPort());
if (Pixmap->Layer() >= 0)
pixmaps[0]->MarkViewPortDirty(Pixmap->ViewPort());
delete Pixmap;
pixmaps[i] = NULL;
return;
@ -1737,9 +1747,9 @@ cPixmap *cOsd::AddPixmap(cPixmap *Pixmap)
return Pixmap;
}
cPixmapMemory *cOsd::RenderPixmaps(void)
cPixmap *cOsd::RenderPixmaps(void)
{
cPixmapMemory *Pixmap = NULL;
cPixmap *Pixmap = NULL;
if (isTrueColor) {
LOCK_PIXMAPS;
// Collect overlapping dirty rectangles:
@ -1762,25 +1772,27 @@ cPixmapMemory *cOsd::RenderPixmaps(void)
d.Combine(OldDirty);
OldDirty = NewDirty;
#endif
Pixmap = new cPixmapMemory(0, d);
Pixmap->Clear();
// Render the individual pixmaps into the resulting pixmap:
for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) {
for (int i = 0; i < pixmaps.Size(); i++) {
if (cPixmap *pm = pixmaps[i]) {
if (pm->Layer() == Layer)
Pixmap->DrawPixmap(pm, d);
Pixmap = CreatePixmap(-1, d);
if (Pixmap) {
Pixmap->Clear();
// Render the individual pixmaps into the resulting pixmap:
for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) {
for (int i = 0; i < pixmaps.Size(); i++) {
if (cPixmap *pm = pixmaps[i]) {
if (pm->Layer() == Layer)
Pixmap->DrawPixmap(pm, d);
}
}
}
}
}
#ifdef DebugDirty
cPixmapMemory DirtyIndicator(7, NewDirty);
static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
static int DirtyIndicatorIndex = 0;
DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point()));
cPixmapMemory DirtyIndicator(7, NewDirty);
static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
static int DirtyIndicatorIndex = 0;
DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point()));
#endif
}
}
}
return Pixmap;

14
osd.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.h 3.5 2015/01/15 11:23:52 kls Exp $
* $Id: osd.h 3.6 2015/02/11 09:48:02 kls Exp $
*/
#ifndef __OSD_H
@ -763,12 +763,13 @@ protected:
///< the pixmap could not be added to the list.
///< A derived class that implements its own cPixmap class must call AddPixmap()
///< in order to add a newly created pixmap to the OSD's list of pixmaps.
cPixmapMemory *RenderPixmaps(void);
cPixmap *RenderPixmaps(void);
///< Renders the dirty part of all pixmaps into a resulting pixmap that
///< shall be displayed on the OSD. The returned pixmap's view port is
///< set to the location of the rectangle on the OSD that needs to be
///< refreshed; its draw port's origin is at (0, 0), and it has the same
///< size as the view port.
///< Only pixmaps with a non-negative layer value are rendered.
///< If there are several non-overlapping dirty rectangles from different pixmaps,
///< they are returned separately in order to avoid re-rendering large parts
///< of the OSD that haven't changed at all. The caller must therefore call
@ -778,7 +779,7 @@ protected:
///< by putting a LOCK_PIXMAPS into the scope of the operation).
///< If there are no dirty pixmaps, or if this is not a true color OSD,
///< this function returns NULL.
///< The caller must delete the returned pixmap after use.
///< The caller must call DestroyPixmap() for the returned pixmap after use.
public:
virtual ~cOsd();
///< Shuts down the OSD.
@ -930,13 +931,16 @@ public:
///< pixmaps, the Flush() function should basically do something like this:
///<
///< LOCK_PIXMAPS;
///< while (cPixmapMemory *pm = RenderPixmaps()) {
///< while (cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps())) {
///< int w = pm->ViewPort().Width();
///< int h = pm->ViewPort().Height();
///< int d = w * sizeof(tColor);
///< MyOsdDrawPixmap(Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y(), pm->Data(), w, h, h * d);
///< delete pm;
///< DestroyPixmap(pm);
///< }
///<
///< If a plugin uses a derived cPixmap implementation, it needs to use that
///< type instead of cPixmapMemory.
};
#define MAXOSDIMAGES 64