mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
[host] d12: remove extra copies in damage tracking
This commit is contained in:
parent
3b43dcb80d
commit
dc4d93f50a
@ -506,8 +506,19 @@ static bool d12_dd_handleFrameUpdate(DDInstance * this, IDXGIResource * res)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->current->nbDirtyRects =
|
{
|
||||||
requiredSize / sizeof(*this->current->dirtyRects);
|
unsigned nbDirtyRects = requiredSize / sizeof(*this->current->dirtyRects);
|
||||||
|
|
||||||
|
// if there is only one damage rect and it covers the entire frame
|
||||||
|
if (nbDirtyRects == 1 &&
|
||||||
|
this->current->dirtyRects[0].left == 0 &&
|
||||||
|
this->current->dirtyRects[0].top == 0 &&
|
||||||
|
this->current->dirtyRects[0].right == this->current->format.Width &&
|
||||||
|
this->current->dirtyRects[0].bottom == this->current->format.Height)
|
||||||
|
goto fullDamage;
|
||||||
|
|
||||||
|
this->current->nbDirtyRects = nbDirtyRects;
|
||||||
|
}
|
||||||
|
|
||||||
DXGI_OUTDUPL_MOVE_RECT moveRects[
|
DXGI_OUTDUPL_MOVE_RECT moveRects[
|
||||||
(ARRAY_LENGTH(this->current->dirtyRects) - this->current->nbDirtyRects) / 2
|
(ARRAY_LENGTH(this->current->dirtyRects) - this->current->nbDirtyRects) / 2
|
||||||
@ -554,6 +565,7 @@ static bool d12_dd_handleFrameUpdate(DDInstance * this, IDXGIResource * res)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fullDamage:
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/windebug.h"
|
#include "common/windebug.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
|
#include "common/rects.h"
|
||||||
#include "com_ref.h"
|
#include "com_ref.h"
|
||||||
|
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
@ -489,21 +490,30 @@ static CaptureResult d12_waitFrame(unsigned frameBufferIndex,
|
|||||||
frame->hdrPQ = false;
|
frame->hdrPQ = false;
|
||||||
frame->rotation = CAPTURE_ROT_0;
|
frame->rotation = CAPTURE_ROT_0;
|
||||||
|
|
||||||
// if there are too many rects
|
|
||||||
if (unlikely(nbDirtyRects > ARRAY_LENGTH(frame->damageRects)))
|
|
||||||
frame->damageRectsCount = 0;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// send the list of dirty rects for this frame
|
// create a clean list of rects
|
||||||
frame->damageRectsCount = nbDirtyRects;
|
FrameDamageRect allRects[this->nbDirtyRects];
|
||||||
for(unsigned i = 0; i < nbDirtyRects; ++i)
|
unsigned count = 0;
|
||||||
frame->damageRects[i] = (FrameDamageRect)
|
for(const RECT * rect = this->dirtyRects;
|
||||||
{
|
rect < this->dirtyRects + this->nbDirtyRects; ++rect)
|
||||||
.x = dirtyRects[i].left,
|
allRects[count++] = (FrameDamageRect){
|
||||||
.y = dirtyRects[i].top,
|
.x = rect->left,
|
||||||
.width = dirtyRects[i].right - dirtyRects[i].left,
|
.y = rect->top,
|
||||||
.height = dirtyRects[i].bottom - dirtyRects[i].top
|
.width = rect->right - rect->left,
|
||||||
|
.height = rect->bottom - rect->top
|
||||||
};
|
};
|
||||||
|
|
||||||
|
count = rectsMergeOverlapping(allRects, count);
|
||||||
|
|
||||||
|
// if there are too many rects
|
||||||
|
if (unlikely(count > ARRAY_LENGTH(frame->damageRects)))
|
||||||
|
frame->damageRectsCount = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// send the list of dirty rects for this frame
|
||||||
|
frame->damageRectsCount = count;
|
||||||
|
memcpy(frame->damageRects, allRects, sizeof(*allRects) * count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = CAPTURE_RESULT_OK;
|
result = CAPTURE_RESULT_OK;
|
||||||
@ -586,22 +596,54 @@ static CaptureResult d12_getFrame(unsigned frameBufferIndex,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* we must update the rects that were dirty in the prior frame also,
|
/* if the prior frame was a full update */
|
||||||
* otherwise the frame in memory will not be consistent when areas need to
|
if (this->nbDirtyRects == 0)
|
||||||
* be redrawn by the client, such as under the cursor */
|
|
||||||
if (this->nbDirtyRects > 0)
|
|
||||||
{
|
{
|
||||||
|
/* the prior frame was fully damaged, we must update everything */
|
||||||
|
ID3D12GraphicsCommandList_CopyTextureRegion(
|
||||||
|
*this->copyCommand.gfxList, &dstLoc, 0, 0, 0, &srcLoc, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FrameDamageRect allRects[this->nbDirtyRects + nbDirtyRects];
|
||||||
|
unsigned count = 0;
|
||||||
|
|
||||||
|
/* we must update the rects that were dirty in the prior frame also,
|
||||||
|
* otherwise the frame in memory will not be consistent when areas need to
|
||||||
|
* be redrawn by the client, such as under the cursor */
|
||||||
for(const RECT * rect = this->dirtyRects;
|
for(const RECT * rect = this->dirtyRects;
|
||||||
rect < this->dirtyRects + this->nbDirtyRects; ++rect)
|
rect < this->dirtyRects + this->nbDirtyRects; ++rect)
|
||||||
|
allRects[count++] = (FrameDamageRect){
|
||||||
|
.x = rect->left,
|
||||||
|
.y = rect->top,
|
||||||
|
.width = rect->right - rect->left,
|
||||||
|
.height = rect->bottom - rect->top
|
||||||
|
};
|
||||||
|
|
||||||
|
/* add the new dirtyRects to the array */
|
||||||
|
for(const RECT * rect = dirtyRects;
|
||||||
|
rect < dirtyRects + nbDirtyRects; ++rect)
|
||||||
|
allRects[count++] = (FrameDamageRect){
|
||||||
|
.x = rect->left,
|
||||||
|
.y = rect->top,
|
||||||
|
.width = rect->right - rect->left,
|
||||||
|
.height = rect->bottom - rect->top
|
||||||
|
};
|
||||||
|
|
||||||
|
/* resolve the rects */
|
||||||
|
count = rectsMergeOverlapping(allRects, count);
|
||||||
|
|
||||||
|
/* copy all the rects */
|
||||||
|
for(FrameDamageRect * rect = allRects; rect < allRects + count; ++rect)
|
||||||
{
|
{
|
||||||
D3D12_BOX box =
|
D3D12_BOX box =
|
||||||
{
|
{
|
||||||
.left = rect->left,
|
.left = rect->x,
|
||||||
.top = rect->top,
|
.top = rect->y,
|
||||||
.front = 0,
|
.front = 0,
|
||||||
.back = 1,
|
.back = 1,
|
||||||
.right = rect->right,
|
.right = rect->x + rect->width,
|
||||||
.bottom = rect->bottom
|
.bottom = rect->y + rect->height
|
||||||
};
|
};
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_CopyTextureRegion(
|
ID3D12GraphicsCommandList_CopyTextureRegion(
|
||||||
@ -610,24 +652,6 @@ static CaptureResult d12_getFrame(unsigned frameBufferIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the frame with the new dirty areas */
|
|
||||||
for(const RECT * rect = dirtyRects; rect < dirtyRects + nbDirtyRects; ++rect)
|
|
||||||
{
|
|
||||||
D3D12_BOX box =
|
|
||||||
{
|
|
||||||
.left = rect->left,
|
|
||||||
.top = rect->top,
|
|
||||||
.front = 0,
|
|
||||||
.back = 1,
|
|
||||||
.right = rect->right,
|
|
||||||
.bottom = rect->bottom
|
|
||||||
};
|
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_CopyTextureRegion(
|
|
||||||
*this->copyCommand.gfxList, &dstLoc,
|
|
||||||
box.left, box.top, 0, &srcLoc, &box);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store the dirty rects for the next frame */
|
/* store the dirty rects for the next frame */
|
||||||
memcpy(this->dirtyRects, dirtyRects,
|
memcpy(this->dirtyRects, dirtyRects,
|
||||||
nbDirtyRects * sizeof(*this->dirtyRects));
|
nbDirtyRects * sizeof(*this->dirtyRects));
|
||||||
|
Loading…
Reference in New Issue
Block a user