1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed rendering pixmaps in case there is more than one dirty rectangle

This commit is contained in:
Klaus Schmidinger 2011-02-27 11:57:37 +01:00
parent 8253754cc3
commit cd3c26b815
2 changed files with 44 additions and 46 deletions

78
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.c 2.15 2011/02/27 10:14:43 kls Exp $ * $Id: osd.c 2.16 2011/02/27 11:57:37 kls Exp $
*/ */
#include "osd.h" #include "osd.h"
@ -949,7 +949,7 @@ void cPixmap::SetLayer(int Layer)
esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1); esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1);
Layer = MAXPIXMAPLAYERS - 1; Layer = MAXPIXMAPLAYERS - 1;
} }
if (Layer && Layer != layer) { if (Layer != layer) {
if (Layer > 0 || layer > 0) if (Layer > 0 || layer > 0)
MarkViewPortDirty(viewPort); MarkViewPortDirty(viewPort);
layer = Layer; layer = Layer;
@ -1089,7 +1089,7 @@ void cPixmapMemory::Fill(tColor Color)
Unlock(); Unlock();
} }
void cPixmap::DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty, bool Opaque) void cPixmap::DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty)
{ {
if (Pixmap->Tile() && (Pixmap->DrawPort().Point() != cPoint(0, 0) || Pixmap->DrawPort().Size() < Pixmap->ViewPort().Size())) { if (Pixmap->Tile() && (Pixmap->DrawPort().Point() != cPoint(0, 0) || Pixmap->DrawPort().Size() < Pixmap->ViewPort().Size())) {
cPoint t0 = Pixmap->DrawPort().Point().Shifted(Pixmap->ViewPort().Point()); // the origin of the draw port in absolute OSD coordinates cPoint t0 = Pixmap->DrawPort().Point().Shifted(Pixmap->ViewPort().Point()); // the origin of the draw port in absolute OSD coordinates
@ -1112,7 +1112,7 @@ void cPixmap::DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty, bool Opaque)
Source.Shift(Delta); // Source is now back at the pixmap's draw port location, still in absolute OSD coordinates Source.Shift(Delta); // Source is now back at the pixmap's draw port location, still in absolute OSD coordinates
Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's view port again Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's view port again
Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data
if (Opaque) if (Pixmap->Layer() == 0)
Copy(Pixmap, Source, Dest); // this is the "background" pixmap Copy(Pixmap, Source, Dest); // this is the "background" pixmap
else else
Render(Pixmap, Source, Dest); // all others are alpha blended over the background Render(Pixmap, Source, Dest); // all others are alpha blended over the background
@ -1132,7 +1132,7 @@ void cPixmap::DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty, bool Opaque)
cPoint Dest = Source.Point().Shifted(-ViewPort().Point()); // remember the destination point cPoint Dest = Source.Point().Shifted(-ViewPort().Point()); // remember the destination point
Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's draw port again Source.Shift(-Pixmap->ViewPort().Point()); // Source is now relative to the pixmap's draw port again
Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data Source.Shift(-Pixmap->DrawPort().Point()); // Source is now relative to the pixmap's data
if (Opaque) if (Pixmap->Layer() == 0)
Copy(Pixmap, Source, Dest); // this is the "background" pixmap Copy(Pixmap, Source, Dest); // this is the "background" pixmap
else else
Render(Pixmap, Source, Dest); // all others are alpha blended over the background Render(Pixmap, Source, Dest); // all others are alpha blended over the background
@ -1662,46 +1662,44 @@ cPixmapMemory *cOsd::RenderPixmaps(void)
cPixmapMemory *Pixmap = NULL; cPixmapMemory *Pixmap = NULL;
if (isTrueColor) { if (isTrueColor) {
LOCK_PIXMAPS; LOCK_PIXMAPS;
for (;;) { // Collect overlapping dirty rectangles:
// Collect overlapping dirty rectangles: cRect d;
cRect d; for (int i = 0; i < numPixmaps; i++) {
for (int i = 0; i < numPixmaps; i++) { cPixmap *pm = pixmaps[i];
cPixmap *pm = pixmaps[i]; if (!pm->DirtyViewPort().IsEmpty()) {
if (!pm->DirtyViewPort().IsEmpty()) { if (d.IsEmpty() || d.Intersects(pm->DirtyViewPort())) {
if (d.IsEmpty() || d.Intersects(pm->DirtyViewPort())) { d.Combine(pm->DirtyViewPort());
d.Combine(pm->DirtyViewPort()); pm->SetClean();
pm->SetClean(); }
} }
} }
} if (!d.IsEmpty()) {
if (d.IsEmpty())
break;
//#define DebugDirty //#define DebugDirty
#ifdef DebugDirty #ifdef DebugDirty
static cRect OldDirty; static cRect OldDirty;
cRect NewDirty = d; cRect NewDirty = d;
d.Combine(OldDirty); d.Combine(OldDirty);
OldDirty = NewDirty; OldDirty = NewDirty;
#endif #endif
Pixmap = new cPixmapMemory(0, d); Pixmap = new cPixmapMemory(0, d);
Pixmap->Clear(); Pixmap->Clear();
// Render the individual pixmaps into the resulting pixmap: // Render the individual pixmaps into the resulting pixmap:
for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) { for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) {
for (int i = 0; i < numPixmaps; i++) { for (int i = 0; i < numPixmaps; i++) {
cPixmap *pm = pixmaps[i]; cPixmap *pm = pixmaps[i];
if (pm->Layer() == Layer) if (pm->Layer() == Layer)
Pixmap->DrawPixmap(pm, d, i == 0); Pixmap->DrawPixmap(pm, d);
} }
} }
#ifdef DebugDirty #ifdef DebugDirty
cPixmapMemory DirtyIndicator(7, NewDirty); cPixmapMemory DirtyIndicator(7, NewDirty);
static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF }; static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
static int DirtyIndicatorIndex = 0; static int DirtyIndicatorIndex = 0;
DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]); DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
DirtyIndicatorIndex = 1 - DirtyIndicatorIndex; DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point())); Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point()));
#endif #endif
} }
} }
return Pixmap; return Pixmap;
} }

12
osd.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.h 2.8 2011/02/26 14:10:30 kls Exp $ * $Id: osd.h 2.9 2011/02/27 11:40:02 kls Exp $
*/ */
#ifndef __OSD_H #ifndef __OSD_H
@ -465,9 +465,11 @@ protected:
///< The coordinates of Point are relative to the pixmap's draw port. ///< The coordinates of Point are relative to the pixmap's draw port.
///< If Point is within the currently visible view port of this pixmap, ///< If Point is within the currently visible view port of this pixmap,
///< MarkViewPortDirty() is called with the appropriate value. ///< MarkViewPortDirty() is called with the appropriate value.
virtual void DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty, bool Opaque); void SetClean(void);
///< Draws the Dirty part of the given Pixmap into this pixmap. If Opaque ///< Resets the "dirty" rectangles of this pixmap.
///< is true, the Pixmap is copied, otherwise it is rendered into this virtual void DrawPixmap(const cPixmap *Pixmap, const cRect &Dirty);
///< Draws the Dirty part of the given Pixmap into this pixmap. If the
///< Pixmap's layer is 0, it is copied, otherwise it is rendered into this
///< pixmap. This function is used only to implement the tile handling ///< pixmap. This function is used only to implement the tile handling
///< in the final rendering to the OSD. ///< in the final rendering to the OSD.
public: public:
@ -524,8 +526,6 @@ public:
///< the surrounding rectangle around all pixels that have been modified since the ///< the surrounding rectangle around all pixels that have been modified since the
///< last time this pixmap has been rendered to the OSD. The rectangle is ///< last time this pixmap has been rendered to the OSD. The rectangle is
///< relative to the draw port's origin. ///< relative to the draw port's origin.
void SetClean(void);
///< Resets the "dirty" rectangles of this pixmap.
virtual void SetLayer(int Layer); virtual void SetLayer(int Layer);
///< Sets the layer of this pixmap to the given value. ///< Sets the layer of this pixmap to the given value.
///< If the new layer is greater than zero, the pixmap will be visible. ///< If the new layer is greater than zero, the pixmap will be visible.