damage: initial attempt at a damage marker mechanism
- This should allow drivers to recieve post submission events for X<->opengl synchronisation. - Lacking a testcase, i'm open to suggestion how to do it better. - The idea is: - driver recieves event - driver creates personal identification and inserts marker into X fifo. - when something wants to use an X pixmap, it checks if something is pending. - If so, it synchronizes the 2nd fifo using the initial identification. - Driver is not required to use interrupt based systems (price too high). - Lower latency is ofcource better. - If this is somehow unusable for you, then come up with improvements. - For that reason i wouldn't consider the api fixed for the moment.
This commit is contained in:
parent
454cb0802e
commit
974db58f5b
|
@ -168,6 +168,48 @@ damageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pDamageRegion)
|
||||||
|
{
|
||||||
|
BoxRec tmpBox;
|
||||||
|
RegionRec tmpRegion, newDamage;
|
||||||
|
Bool was_empty;
|
||||||
|
|
||||||
|
REGION_UNION(pScreem, &newDamage, pOldDamage, pDamageRegion);
|
||||||
|
|
||||||
|
switch (pDamage->damageLevel) {
|
||||||
|
case DamageReportRawRegion:
|
||||||
|
(*pDamage->damageReportPostRendering) (pDamage, pDamageRegion, pDamage->closure);
|
||||||
|
break;
|
||||||
|
case DamageReportDeltaRegion:
|
||||||
|
REGION_NULL (pScreen, &tmpRegion);
|
||||||
|
REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, pOldDamage);
|
||||||
|
if (REGION_NOTEMPTY (pScreen, &tmpRegion)) {
|
||||||
|
(*pDamage->damageReportPostRendering) (pDamage, &tmpRegion, pDamage->closure);
|
||||||
|
}
|
||||||
|
REGION_UNINIT(pScreen, &tmpRegion);
|
||||||
|
break;
|
||||||
|
case DamageReportBoundingBox:
|
||||||
|
tmpBox = *REGION_EXTENTS (pScreen, pOldDamage);
|
||||||
|
if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &newDamage))) {
|
||||||
|
(*pDamage->damageReportPostRendering) (pDamage, &newDamage,
|
||||||
|
pDamage->closure);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DamageReportNonEmpty:
|
||||||
|
was_empty = !REGION_NOTEMPTY(pScreen, pOldDamage);
|
||||||
|
if (was_empty && REGION_NOTEMPTY(pScreen, &newDamage)) {
|
||||||
|
(*pDamage->damageReportPostRendering) (pDamage, &newDamage,
|
||||||
|
pDamage->closure);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DamageReportNone:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_UNINIT(pScreen, &newDamage);
|
||||||
|
}
|
||||||
|
|
||||||
#if DAMAGE_DEBUG_ENABLE
|
#if DAMAGE_DEBUG_ENABLE
|
||||||
static void
|
static void
|
||||||
_damageRegionPending (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
|
_damageRegionPending (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
|
||||||
|
@ -306,15 +348,22 @@ damageRegionPending (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
|
||||||
if (draw_x || draw_y)
|
if (draw_x || draw_y)
|
||||||
REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
|
REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
|
||||||
|
|
||||||
/* If the damage rec has been flagged to report damage after the op has
|
/* Store damage region if needed after submission. */
|
||||||
* completed, then union it into the delayed damage region, which will
|
if (pDamage->reportAfter || pDamage->damageMarker)
|
||||||
* be used for reporting after calling down, and skip the reporting
|
|
||||||
*/
|
|
||||||
if (!pDamage->reportAfter) {
|
|
||||||
damageReportDamage (pDamage, pDamageRegion);
|
|
||||||
} else {
|
|
||||||
REGION_UNION(pScreen, &pDamage->pendingDamage,
|
REGION_UNION(pScreen, &pDamage->pendingDamage,
|
||||||
&pDamage->pendingDamage, pDamageRegion);
|
&pDamage->pendingDamage, pDamageRegion);
|
||||||
|
|
||||||
|
/* Duplicate current damage if needed. */
|
||||||
|
if (pDamage->damageMarker)
|
||||||
|
REGION_COPY(pScreen, &pDamage->backupDamage, &pDamage->damage);
|
||||||
|
|
||||||
|
/* Report damage now, if desired. */
|
||||||
|
if (!pDamage->reportAfter) {
|
||||||
|
if (pDamage->damageReport)
|
||||||
|
damageReportDamage (pDamage, pDamageRegion);
|
||||||
|
else
|
||||||
|
REGION_UNION(pScreen, &pDamage->damage,
|
||||||
|
&pDamage->damage, pDamageRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -338,10 +387,22 @@ damageRegionSubmitted (DrawablePtr pDrawable)
|
||||||
|
|
||||||
for (; pDamage != NULL; pDamage = pDamage->pNext)
|
for (; pDamage != NULL; pDamage = pDamage->pNext)
|
||||||
{
|
{
|
||||||
|
/* submit damage marker whenever possible. */
|
||||||
|
if (pDamage->damageMarker)
|
||||||
|
(*pDamage->damageMarker) (pDrawable, pDamage, &pDamage->backupDamage, &pDamage->pendingDamage, pDamage->closure);
|
||||||
if (pDamage->reportAfter) {
|
if (pDamage->reportAfter) {
|
||||||
damageReportDamage (pDamage, &pDamage->pendingDamage);
|
/* It's possible that there is only interest in postRendering reporting. */
|
||||||
REGION_EMPTY (pScreen, &pDamage->pendingDamage);
|
if (pDamage->damageReport)
|
||||||
|
damageReportDamage (pDamage, &pDamage->pendingDamage);
|
||||||
|
else
|
||||||
|
REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
|
||||||
|
&pDamage->pendingDamage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pDamage->reportAfter || pDamage->damageMarker)
|
||||||
|
REGION_EMPTY (pScreen, &pDamage->pendingDamage);
|
||||||
|
if (pDamage->damageMarker)
|
||||||
|
REGION_EMPTY (pScreen, &pDamage->backupDamage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1810,7 +1871,9 @@ DamageCreate (DamageReportFunc damageReport,
|
||||||
pDamage->reportAfter = FALSE;
|
pDamage->reportAfter = FALSE;
|
||||||
|
|
||||||
pDamage->damageReport = damageReport;
|
pDamage->damageReport = damageReport;
|
||||||
|
pDamage->damageReportPostRendering = NULL;
|
||||||
pDamage->damageDestroy = damageDestroy;
|
pDamage->damageDestroy = damageDestroy;
|
||||||
|
pDamage->damageMarker = NULL;
|
||||||
return pDamage;
|
return pDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1934,7 +1997,7 @@ DamageEmpty (DamagePtr pDamage)
|
||||||
REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
|
REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionPtr
|
_X_EXPORT RegionPtr
|
||||||
DamageRegion (DamagePtr pDamage)
|
DamageRegion (DamagePtr pDamage)
|
||||||
{
|
{
|
||||||
return &pDamage->damage;
|
return &pDamage->damage;
|
||||||
|
@ -1958,6 +2021,16 @@ DamageRegionSubmitted (DrawablePtr pDrawable)
|
||||||
damageRegionSubmitted (pDrawable);
|
damageRegionSubmitted (pDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If a damage marker is provided, then this function must be called after rendering is done. */
|
||||||
|
/* Please do call back so any future enhancements can assume this function is called. */
|
||||||
|
/* There are no strict timing requirements for calling this function, just as soon as (is cheaply) possible. */
|
||||||
|
_X_EXPORT void
|
||||||
|
DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion)
|
||||||
|
{
|
||||||
|
if (pDamage->damageReportPostRendering)
|
||||||
|
damageReportDamagePostRendering (pDamage, pOldDamage, pRegion);
|
||||||
|
}
|
||||||
|
|
||||||
/* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */
|
/* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */
|
||||||
_X_EXPORT void
|
_X_EXPORT void
|
||||||
DamageDamageRegion (DrawablePtr pDrawable,
|
DamageDamageRegion (DrawablePtr pDrawable,
|
||||||
|
@ -1972,8 +2045,16 @@ DamageDamageRegion (DrawablePtr pDrawable,
|
||||||
damageRegionSubmitted (pDrawable);
|
damageRegionSubmitted (pDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
_X_EXPORT void
|
||||||
DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter)
|
DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter)
|
||||||
{
|
{
|
||||||
pDamage->reportAfter = reportAfter;
|
pDamage->reportAfter = reportAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_X_EXPORT void
|
||||||
|
DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering,
|
||||||
|
DamageMarkerFunc damageMarker)
|
||||||
|
{
|
||||||
|
pDamage->damageReportPostRendering = damageReportPostRendering;
|
||||||
|
pDamage->damageMarker = damageMarker;
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ typedef enum _damageReportLevel {
|
||||||
|
|
||||||
typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure);
|
typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure);
|
||||||
typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure);
|
typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure);
|
||||||
|
/* It's the responsibility of the driver to duplicate both regions. */
|
||||||
|
/* At some point DamageRegionRendered() must be called. */
|
||||||
|
typedef void (*DamageMarkerFunc) (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion, void *closure);
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
DamageSetup (ScreenPtr pScreen);
|
DamageSetup (ScreenPtr pScreen);
|
||||||
|
@ -86,6 +89,10 @@ DamageRegionPending (DrawablePtr pDrawable, RegionPtr pRegion);
|
||||||
void
|
void
|
||||||
DamageRegionSubmitted (DrawablePtr pDrawable);
|
DamageRegionSubmitted (DrawablePtr pDrawable);
|
||||||
|
|
||||||
|
/* Call this some time after rendering is done, only relevant when a damageMarker is provided. */
|
||||||
|
void
|
||||||
|
DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion);
|
||||||
|
|
||||||
/* Avoid using this call, it only exists for API compatibility. */
|
/* Avoid using this call, it only exists for API compatibility. */
|
||||||
void
|
void
|
||||||
DamageDamageRegion (DrawablePtr pDrawable,
|
DamageDamageRegion (DrawablePtr pDrawable,
|
||||||
|
@ -94,4 +101,8 @@ DamageDamageRegion (DrawablePtr pDrawable,
|
||||||
void
|
void
|
||||||
DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter);
|
DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter);
|
||||||
|
|
||||||
|
void
|
||||||
|
DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering,
|
||||||
|
DamageMarkerFunc damageMarker);
|
||||||
|
|
||||||
#endif /* _DAMAGE_H_ */
|
#endif /* _DAMAGE_H_ */
|
||||||
|
|
|
@ -46,10 +46,13 @@ typedef struct _damage {
|
||||||
DrawablePtr pDrawable;
|
DrawablePtr pDrawable;
|
||||||
|
|
||||||
DamageReportFunc damageReport;
|
DamageReportFunc damageReport;
|
||||||
|
DamageReportFunc damageReportPostRendering;
|
||||||
DamageDestroyFunc damageDestroy;
|
DamageDestroyFunc damageDestroy;
|
||||||
|
DamageMarkerFunc damageMarker;
|
||||||
|
|
||||||
Bool reportAfter;
|
Bool reportAfter;
|
||||||
RegionRec pendingDamage;
|
RegionRec pendingDamage; /* will be flushed post submission at the latest */
|
||||||
|
RegionRec backupDamage; /* for use with damageMarker */
|
||||||
} DamageRec;
|
} DamageRec;
|
||||||
|
|
||||||
typedef struct _damageScrPriv {
|
typedef struct _damageScrPriv {
|
||||||
|
|
Loading…
Reference in New Issue