forked from 12to11/12to11
Rework subcompositor damage culling and use a back buffer in the pict renderer
Note that the EGL renderer has been broken by these changes. * compositor.h (struct _RenderFuncs): Change arguments to `finish_render'. Add `cancel_completion_callback'. Remove `cancel_presentation'. (struct _BufferFuncs): Add `is_buffer_opaque'. * egl.c: Note that the EGL renderer is currently broken. * fence_ring.c (FenceFree, struct _Fence, GetFence, FenceAwait) (FenceToXFence): Repurpose fence code as a generic allocator of fences. * frame_clock.c (EndFrame): Adjust calculation of even value. * picture_renderer.c (struct _BufferActivityRecord): Remove `fence'. (struct _PictureBuffer): Remove unused field. (struct _PresentCompletionCallback): Remove unused fields linking it to the target. (struct _BackBuffer): New structure. (IsBufferBusy, SetBufferBusy, ClearBufferBusy): New macros. (struct _PictureTarget): Add back buffer and GC fields. (use_sync_fences): Remove variable. (RecordBufferActivity): Don't take fence. (UnlinkActivityRecord): Don't wait on fence. (FreeBackBuffer, FreeBackBuffers, CreateBackBuffer) (MakePresentationCallback, SwapBackBuffers) (SwapBackBuffersWithCopy, MaybeAwaitBuffer, GetNextBackBuffer) (EnsurePicture): New functions. (TargetFromDrawable): Don't create picture for window targets, and create GC for those. (NoteTargetSize): Free back buffers instead of creating presentation windows. (DestroyRenderTarget): Free back buffers. (ViewContainsExtents): Delete function. (FinishRender): Swap back buffers and handle callbacks. (CancelCompletionCallback): New function. (TargetAge): Implement accordingly. (PresentToWindow, CancelPresentationCallback): Present to the regular window instead of a separate ``presentation window''. (CancelPresentation): Remove function. (picture_render_funcs): Add CancelCompletionCallback; remove NeverAges and CancelPresentation. (BufferFromDmaBuf, FinishDmaBufRecord, BufferFromShm): Set opaque flag accordingly. (IsBufferOpaque): New function. (picture_buffer_funcs): Add IsBufferOpaque. (HandlePresentCompleteNotify, HandlePresentIdleNotify): Handle back buffer release. * renderer.c (RenderFinishRender, RenderCancelCompletionCallback) (RenderCancelPresentation, RenderIsBufferOpaque): Adjust accordingly. * seat.c (InterpolateAxes): Fix NULL-pointer dereference. * subcompositor.c (SetFrozen, IsFrozen): Get rid of unused state. (struct _View): Cache the width and height. Add cull_region field. (struct _Subcompositor): Add `render_key' field. (ViewAfterSizeUpdate): Set cached width and height. (ViewAttachBuffer): Correctly handle size changes. (ViewDamage): Apply buffer damage. (ViewDamageBuffer): use ViewDamage. (ApplyBufferDamage): New function.:(FillBoxesWithTransparency, ViewContainsExtents, IntersectBoxes): Delete unused functions. (RenderCompletedCallback): New function. (NoViewsAfter): Delete function. (SkipSlug): New slug. (SubcompositorUpdateAncillary, TryPresent, AnyParentUnmapped) (DoCull, DrawBackground, CompositeSingleView, InitBackground) (SubcompositorComposite1, SubcompositorComposite): New functions. Implement new redisplay logic here. (SubcompositorUpdate, CopyRegion): New function. (SubcompositorExpose, SubcompositorFree): Clear render callback if set. (SubcompositorLookupView): Use cached width and height. (SubcompositorFreeze, SubcompositorUnfreeze): Remove unused functions. * time.c (InitTime): Fix use of uninitialized value initializing the Sync extension. * transform.c (TransformBox): Pacify compiler warning.
This commit is contained in:
parent
0b5d44537b
commit
a05a62d9d0
10 changed files with 1447 additions and 1349 deletions
52
compositor.h
52
compositor.h
|
@ -161,12 +161,14 @@ typedef enum _BufferTransform BufferTransform;
|
|||
|
||||
typedef void *IdleCallbackKey;
|
||||
typedef void *PresentCompletionKey;
|
||||
typedef void *RenderCompletionKey;
|
||||
|
||||
typedef void (*DmaBufSuccessFunc) (RenderBuffer, void *);
|
||||
typedef void (*DmaBufFailureFunc) (void *);
|
||||
|
||||
typedef void (*BufferIdleFunc) (RenderBuffer, void *);
|
||||
typedef void (*PresentCompletionFunc) (void *);
|
||||
typedef void (*RenderCompletionFunc) (void *);
|
||||
|
||||
enum _BufferTransform
|
||||
{
|
||||
|
@ -361,20 +363,30 @@ struct _RenderFuncs
|
|||
int, int, int, int, DrawParams *);
|
||||
|
||||
/* Finish rendering, and swap changes in given damage to display.
|
||||
May be NULL. */
|
||||
void (*finish_render) (RenderTarget, pixman_region32_t *);
|
||||
May be NULL. If a callback is passed and a non-NULL key is
|
||||
returned, then the rendering will not actually have finished
|
||||
until the callback is run. */
|
||||
RenderCompletionKey (*finish_render) (RenderTarget, pixman_region32_t *,
|
||||
RenderCompletionFunc, void *);
|
||||
|
||||
/* Cancel the callback returned by finish_render. */
|
||||
void (*cancel_completion_callback) (RenderCompletionKey);
|
||||
|
||||
/* Return the age of the target. Value is a number not less than
|
||||
-1, describing the "age" of the contents of the target.
|
||||
|
||||
-2, describing the "age" of the contents of the target.
|
||||
|
||||
-1 means the buffer contains no valid contents, and must be
|
||||
redrawn from scratch. 0 means the buffer contains the contents
|
||||
at the time of the last call to `finish_render', 1 means the
|
||||
buffer contains the contents at the time of the second last
|
||||
call to `finish_render', and so on.
|
||||
redrawn from scratch. 0 means the buffer contains the contents
|
||||
at the time of the last call to `finish_render', 1 means the
|
||||
buffer contains the contents at the time of the second last call
|
||||
to `finish_render', and so on.
|
||||
|
||||
Note that when a render target is first created, the renderer
|
||||
may chose to return 0 instead of 1. */
|
||||
-2 means the buffer contents are of the last call to
|
||||
FinishRender, but are invalid for any rendering call other than
|
||||
present_to_window.
|
||||
|
||||
Note that when a render target is first created, the renderer may
|
||||
chose to return 0 instead of 1. */
|
||||
int (*target_age) (RenderTarget);
|
||||
|
||||
/* Create a rendering "fence" object, that serves to explicitly
|
||||
|
@ -407,11 +419,6 @@ struct _RenderFuncs
|
|||
|
||||
/* Cancel the given presentation callback. */
|
||||
void (*cancel_presentation_callback) (PresentCompletionKey);
|
||||
|
||||
/* Cancel any presentation that might have happened to the window
|
||||
backing the given target. This must be called before any normal
|
||||
drawing operations. */
|
||||
void (*cancel_presentation) (RenderTarget);
|
||||
|
||||
/* Some flags. NeverAges means targets always preserve contents
|
||||
that were previously drawn. */
|
||||
|
@ -512,6 +519,10 @@ struct _BufferFuncs
|
|||
/* Ensure wait_for_idle can be called. May be NULL. */
|
||||
void (*set_need_wait_for_idle) (RenderTarget);
|
||||
|
||||
/* Return whether or not the given buffer can be treated as
|
||||
completely opaque. */
|
||||
Bool (*is_buffer_opaque) (RenderBuffer);
|
||||
|
||||
/* Called during renderer initialization. */
|
||||
void (*init_buffer_funcs) (void);
|
||||
};
|
||||
|
@ -535,7 +546,11 @@ extern void RenderFillBoxesWithTransparency (RenderTarget, pixman_box32_t *,
|
|||
extern void RenderClearRectangle (RenderTarget, int, int, int, int);
|
||||
extern void RenderComposite (RenderBuffer, RenderTarget, Operation, int,
|
||||
int, int, int, int, int, DrawParams *);
|
||||
extern void RenderFinishRender (RenderTarget, pixman_region32_t *);
|
||||
extern RenderCompletionKey RenderFinishRender (RenderTarget,
|
||||
pixman_region32_t *,
|
||||
RenderCompletionFunc,
|
||||
void *);
|
||||
extern void RenderCancelCompletionCallback (RenderCompletionKey);
|
||||
extern int RenderTargetAge (RenderTarget);
|
||||
extern RenderFence RenderImportFdFence (int, Bool *);
|
||||
extern void RenderWaitFence (RenderFence);
|
||||
|
@ -546,7 +561,6 @@ extern PresentCompletionKey RenderPresentToWindow (RenderTarget, RenderBuffer,
|
|||
PresentCompletionFunc,
|
||||
void *);
|
||||
extern void RenderCancelPresentationCallback (PresentCompletionKey);
|
||||
extern void RenderCancelPresentation (RenderTarget);
|
||||
|
||||
extern DrmFormat *RenderGetDrmFormats (int *);
|
||||
extern dev_t RenderGetRenderDevice (Bool *);
|
||||
|
@ -571,6 +585,7 @@ extern void RenderCancelIdleCallback (IdleCallbackKey);
|
|||
extern Bool RenderIsBufferIdle (RenderBuffer, RenderTarget);
|
||||
extern void RenderWaitForIdle (RenderBuffer, RenderTarget);
|
||||
extern void RenderSetNeedWaitForIdle (RenderTarget);
|
||||
extern Bool RenderIsBufferOpaque (RenderBuffer);
|
||||
|
||||
/* Defined in run.c. */
|
||||
|
||||
|
@ -1760,8 +1775,11 @@ extern int ProcessPoll (struct pollfd *, nfds_t, struct timespec *);
|
|||
typedef struct _Fence Fence;
|
||||
|
||||
extern Fence *GetFence (void);
|
||||
extern Fence *GetLooseFence (void);
|
||||
extern void FenceTrigger (Fence *);
|
||||
extern void FenceRetain (Fence *);
|
||||
extern void FenceAwait (Fence *);
|
||||
extern void FenceRelease (Fence *);
|
||||
extern XSyncFence FenceToXFence (Fence *);
|
||||
|
||||
/* Utility functions that don't belong in a specific file. */
|
||||
|
|
3
egl.c
3
egl.c
|
@ -35,7 +35,8 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include "linux-dmabuf-unstable-v1.h"
|
||||
|
||||
/* TODO: implement buffer transforms. */
|
||||
/* TODO: implement buffer transforms. This renderer is currently
|
||||
broken. */
|
||||
|
||||
/* These are flags for the DrmFormats. */
|
||||
|
||||
|
|
68
fence_ring.c
68
fence_ring.c
|
@ -28,28 +28,19 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <xcb/dri3.h>
|
||||
|
||||
#define FenceFree (1U << 31)
|
||||
|
||||
struct _Fence
|
||||
{
|
||||
/* The next and last fences on this list. */
|
||||
Fence *next;
|
||||
|
||||
/* The xshmfence. */
|
||||
struct xshmfence *fence;
|
||||
|
||||
/* The sync fence. High bit is a flag meaning that the fence is on
|
||||
the free list. */
|
||||
/* The sync fence. */
|
||||
XSyncFence fence_id;
|
||||
|
||||
/* The number of references to this fence. Incremented by
|
||||
FenceRetain, decremented by FenceAwait. */
|
||||
FenceRetain, decremented by FenceRelease. */
|
||||
int refcount;
|
||||
};
|
||||
|
||||
/* Chain of all free fences. */
|
||||
static Fence *all_fences;
|
||||
|
||||
Fence *
|
||||
GetFence (void)
|
||||
{
|
||||
|
@ -59,22 +50,7 @@ GetFence (void)
|
|||
|
||||
drawable = DefaultRootWindow (compositor.display);
|
||||
|
||||
/* Get one free fence. */
|
||||
|
||||
for (fence = all_fences; fence; fence = fence->next)
|
||||
{
|
||||
/* Unlink this fence. */
|
||||
all_fences = fence->next;
|
||||
fence->next = NULL;
|
||||
|
||||
/* Mark the fence as used. */
|
||||
fence->fence_id &= ~FenceFree;
|
||||
|
||||
/* Return it. */
|
||||
return fence;
|
||||
}
|
||||
|
||||
/* Otherwise, allocate a new fence. */
|
||||
/* Allocate a new fence. */
|
||||
fence = XLCalloc (1, sizeof *fence);
|
||||
fd = xshmfence_alloc_shm ();
|
||||
|
||||
|
@ -103,6 +79,9 @@ GetFence (void)
|
|||
xcb_dri3_fence_from_fd (compositor.conn, drawable,
|
||||
fence->fence_id, 0, fd);
|
||||
|
||||
/* Retain the fence. */
|
||||
FenceRetain (fence);
|
||||
|
||||
/* Return the fence. */
|
||||
return fence;
|
||||
}
|
||||
|
@ -110,26 +89,27 @@ GetFence (void)
|
|||
void
|
||||
FenceAwait (Fence *fence)
|
||||
{
|
||||
XLAssert (fence->refcount);
|
||||
fence->refcount -= 1;
|
||||
/* Wait for the fence to be triggered. */
|
||||
xshmfence_await (fence->fence);
|
||||
|
||||
if (!(fence->fence_id & FenceFree))
|
||||
{
|
||||
/* Wait for the fence to be triggered. */
|
||||
xshmfence_await (fence->fence);
|
||||
/* Reset the fence. */
|
||||
xshmfence_reset (fence->fence);
|
||||
}
|
||||
|
||||
/* Reset the fence. */
|
||||
xshmfence_reset (fence->fence);
|
||||
fence->fence_id |= FenceFree;
|
||||
}
|
||||
|
||||
if (fence->refcount)
|
||||
void
|
||||
FenceRelease (Fence *fence)
|
||||
{
|
||||
if (--fence->refcount)
|
||||
return;
|
||||
|
||||
/* Now that the fence is no longer referenced, it can be put back on
|
||||
the list of free fences. */
|
||||
fence->next = all_fences;
|
||||
all_fences = fence;
|
||||
/* Unmap the fence. */
|
||||
xshmfence_unmap_shm (fence->fence);
|
||||
|
||||
/* Destroy the fence. */
|
||||
XSyncDestroyFence (compositor.display, fence->fence_id);
|
||||
|
||||
/* Free the fence. */
|
||||
XLFree (fence);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -141,5 +121,5 @@ FenceRetain (Fence *fence)
|
|||
XSyncFence
|
||||
FenceToXFence (Fence *fence)
|
||||
{
|
||||
return fence->fence_id & ~FenceFree;
|
||||
return fence->fence_id;
|
||||
}
|
||||
|
|
|
@ -476,7 +476,12 @@ EndFrame (FrameClock *clock)
|
|||
/* Signal to the compositor that the frame is now complete. When
|
||||
the compositor finishes drawing the frame, a callback will be
|
||||
received. */
|
||||
clock->next_frame_id += 1;
|
||||
|
||||
if (clock->next_frame_id % 4 == 3)
|
||||
clock->next_frame_id += 1;
|
||||
else
|
||||
clock->next_frame_id += 3;
|
||||
|
||||
clock->finished_frame_id = clock->next_frame_id;
|
||||
|
||||
/* The frame has ended. Freeze the frame clock if there is a
|
||||
|
@ -488,8 +493,7 @@ EndFrame (FrameClock *clock)
|
|||
if (!frame_sync_supported)
|
||||
return;
|
||||
|
||||
SetSyncCounter (clock->secondary_counter,
|
||||
clock->next_frame_id);
|
||||
SetSyncCounter (clock->secondary_counter, clock->next_frame_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
File diff suppressed because it is too large
Load diff
30
renderer.c
30
renderer.c
|
@ -145,11 +145,20 @@ RenderComposite (RenderBuffer source, RenderTarget target, Operation op,
|
|||
width, height, draw_params);
|
||||
}
|
||||
|
||||
void
|
||||
RenderFinishRender (RenderTarget target, pixman_region32_t *damage)
|
||||
RenderCompletionKey
|
||||
RenderFinishRender (RenderTarget target, pixman_region32_t *damage,
|
||||
RenderCompletionFunc function, void *data)
|
||||
{
|
||||
if (render_funcs.finish_render)
|
||||
render_funcs.finish_render (target, damage);
|
||||
return render_funcs.finish_render (target, damage, function, data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
RenderCancelCompletionCallback (RenderCompletionKey key)
|
||||
{
|
||||
return render_funcs.cancel_completion_callback (key);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -206,15 +215,6 @@ RenderCancelPresentationCallback (PresentCompletionKey key)
|
|||
render_funcs.cancel_presentation_callback (key);
|
||||
}
|
||||
|
||||
void
|
||||
RenderCancelPresentation (RenderTarget target)
|
||||
{
|
||||
if (!render_funcs.cancel_presentation)
|
||||
return;
|
||||
|
||||
render_funcs.cancel_presentation (target);
|
||||
}
|
||||
|
||||
DrmFormat *
|
||||
RenderGetDrmFormats (int *n_formats)
|
||||
{
|
||||
|
@ -344,6 +344,12 @@ RenderSetNeedWaitForIdle (RenderTarget target)
|
|||
buffer_funcs.set_need_wait_for_idle (target);
|
||||
}
|
||||
|
||||
Bool
|
||||
RenderIsBufferOpaque (RenderBuffer buffer)
|
||||
{
|
||||
return buffer_funcs.is_buffer_opaque (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
RegisterStaticRenderer (const char *name,
|
||||
RenderFuncs *render_funcs,
|
||||
|
|
2
seat.c
2
seat.c
|
@ -3648,6 +3648,8 @@ InterpolateAxes (Surface *surface, DeviceInfo *info,
|
|||
/* Multiply the deltas by 15 if no device was found. */
|
||||
*x_out = movement_x * 15;
|
||||
*y_out = movement_y * 15;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Multiply these deltas by the scrolling pixel distance to obtain
|
||||
|
|
1855
subcompositor.c
1855
subcompositor.c
File diff suppressed because it is too large
Load diff
12
time.c
12
time.c
|
@ -303,12 +303,6 @@ InitTime (void)
|
|||
supported = XSyncInitialize (compositor.display,
|
||||
&xsync_major, &xsync_minor);
|
||||
|
||||
if (xsync_major < 3 || (xsync_major == 3 && xsync_minor < 1))
|
||||
{
|
||||
fprintf (stderr, "Sync fences are not supported by this X server\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
fprintf (stderr, "A compatible version of the synchronization"
|
||||
|
@ -316,6 +310,12 @@ InitTime (void)
|
|||
exit (1);
|
||||
}
|
||||
|
||||
if (xsync_major < 3 || (xsync_major == 3 && xsync_minor < 1))
|
||||
{
|
||||
fprintf (stderr, "Sync fences are not supported by this X server\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Initialize server timestamp tracking. In order for server time
|
||||
accounting to be absolutely reliable, we must receive an event
|
||||
detailing each change every time it reaches HalfMonth and 0. Set
|
||||
|
|
|
@ -345,6 +345,7 @@ TransformBox (pixman_box32_t *box, BufferTransform transform,
|
|||
switch (transform)
|
||||
{
|
||||
case Normal:
|
||||
default:
|
||||
work = *box;
|
||||
break;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue