@@ -381,8 +381,6 @@ struct video_buffer_ops {
381381 struct video_regionlock *__restrict __lock);
382382
383383
384- /* Buffer revocation / sub-region operators */
385-
386384 /* Revoke access to non-anonymous pixel data (and maybe even anonymous) of this video buffer.
387385 * Access to pixel data of any sub-region created from `__self' (or recursively created form
388386 * one of those buffers) is also revoked.
@@ -528,6 +526,64 @@ video_buffer_wlockregion(struct video_buffer *__self, struct video_regionlock *_
528526 * by `video_buffer_rlockregion()' or `video_buffer_wlockregion()'. */
529527extern __ATTR_INOUT (1 ) __ATTR_NONNULL((2 )) void
530528video_buffer_unlockregion(struct video_buffer *__self, struct video_regionlock *__lock);
529+
530+
531+ /* Revoke access to non-anonymous pixel data (and maybe even anonymous) of this video buffer.
532+ * Access to pixel data of any sub-region created from `__self' (or recursively created form
533+ * one of those buffers) is also revoked.
534+ *
535+ * All types of video buffers can have their access revoked, except for buffers returned by
536+ * `video_domain_newbuffer[_ex]()' (though sub-region buffers of those can be revoked, and
537+ * calling this function for one such buffer will do exactly that).
538+ *
539+ * @return: * : Always re-returns `__self' */
540+ extern __ATTR_RETNONNULL __ATTR_INOUT (1 ) struct video_buffer *
541+ __NOTHROW(video_buffer_revoke)(struct video_buffer *__restrict __self);
542+
543+ /* Create a new hard subregion-proxy of `__self'. The caller is responsible to ensure
544+ * that the given `__rect' does not exceed `__self->vb_xdim' / `__self->vb_ydim'. Note
545+ * that this function behaves slightly different from `video_buffer_region()', in that
546+ * the later accepts a signed rect, while also allowing said rect to be greater than
547+ * the dimensions of the original buffer.
548+ *
549+ * On the other hand, this function only works for creating **true** sub-rects, but
550+ * since this one is implemented by individual buffers, it is probably faster, too.
551+ *
552+ * Buffers returned by this function are guarantied to share pixel access with `__self',
553+ * and `video_buffer_revoke' is to `__self' will also revoke access for `return' (either
554+ * directly, by keeping a list of sub-region buffers in `__self', or indirectly, by having
555+ * every access to pixel-data in `return' check if `__self' has been revoked).
556+ *
557+ * NOTE: This function will never re-return `__self', even if `__rect' is the full
558+ * rect of `__self', and `__xor_flags == 0'. This is because doing also cause
559+ * `video_buffer_revoke' invoked on the returned buffer to revoke `__self'.
560+ *
561+ * @assume(__rect->vcr_xdim > 0);
562+ * @assume(__rect->vcr_ydim > 0);
563+ * @assume((__rect->vcr_xmin + __rect->vcr_xdim) > __rect->vcr_xmin);
564+ * @assume((__rect->vcr_ymin + __rect->vcr_ydim) > __rect->vcr_ymin);
565+ * @assume((__rect->vcr_xmin + __rect->vcr_xdim) <= __self->vb_xdim);
566+ * @assume((__rect->vcr_ymin + __rect->vcr_ydim) <= __self->vb_ydim);
567+ * @param: __self: Video buffer to create a sub-region of
568+ * @param: __rect: Sub-region rect of `__self' to-be returned
569+ * @param: __xor_flags: Flags to xor- toggle in GFX contexts created on `return'.
570+ * These flags are NOT applied to `__rect', but they still
571+ * allow you to create sub-region buffers that will appear
572+ * to be natively rotated in `struct video_gfx' contexts.
573+ * Only the following flags *should* be used here. All other
574+ * flags can still be used, but many not necessarily produce
575+ * expected results:
576+ * - VIDEO_GFX_F_XMIRROR
577+ * - VIDEO_GFX_F_YMIRROR
578+ * - VIDEO_GFX_F_XYSWAP
579+ * @return: * : The newly created sub-region buffer
580+ * @return: NULL: [errno=ENOMEM] Insufficient memory
581+ * @return: NULL: [errno=*] Failed to create sub-region for some other reason */
582+ extern __ATTR_WUNUSED __ATTR_INOUT (1 ) __ATTR_IN(2 ) __REF struct video_buffer *
583+ video_buffer_subregion(struct video_buffer *__restrict __self,
584+ struct video_crect const *__restrict __rect,
585+ gfx_flag_t __xor_flags);
586+
531587#else /* __INTELLISENSE__ */
532588#define video_buffer_getgfx (self, result, blendmode, flags, colorkey ) \
533589 ((result)->vx_colorkey = (colorkey), (result)->vx_flags = (flags), \
@@ -549,6 +605,9 @@ video_buffer_unlockregion(struct video_buffer *__self, struct video_regionlock *
549605 (*(self)->vb_ops->vi_wlockregion)(self, lock))
550606#define video_buffer_unlockregion (self, lock ) \
551607 (*(self)->vb_ops->vi_unlockregion)(self, lock)
608+ #define video_buffer_revoke (self ) (*(self)->vb_ops->vi_revoke)(self)
609+ #define video_buffer_subregion (self, rect, xor_flags ) \
610+ (*(self)->vb_ops->vi_subregion)(self, rect, xor_flags)
552611#endif /* !__INTELLISENSE__ */
553612
554613
@@ -785,6 +844,58 @@ video_buffer_lockable(struct video_buffer *__restrict __self);
785844#endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
786845
787846
847+
848+ /* Create a new region-relative-proxy of `__self', that interacts with the same
849+ * pixel data, both during GFX operations, as well when creating video locks.
850+ *
851+ * You can also use this function to create regions at negative offsets, or
852+ * ones that are larger than `__self'. In this case, the returned buffer will
853+ * not be lockable, except when using `video_buffer_r/wlockregion' for regions
854+ * that contain actual pixel data. Similarly, GFX operations for pixel data
855+ * outside the true pixel area (which is enforced by the I/O Rect of any GFX
856+ * created using the returned buffer), will yield "0" during read, and be a
857+ * no-op during write.
858+ *
859+ * Then returned buffer always behaves properly when it comes to being able to
860+ * be revoked, after which point it will never again make any access to pixel
861+ * data of `__self'.
862+ *
863+ * When the given `__rect' is actually a sub-region of `__self', then this
864+ * function will simply make use of `video_buffer_subregion()' and call the
865+ * dedicated video buffer operator for creating sub-regions.
866+ *
867+ * When the returned buffer isn't created as a true sub-region of `__self',
868+ * its `vb_domain' will be set to the return value of `video_ramdomain()'.
869+ *
870+ * @param: __self: Video buffer to create a region of
871+ * @param: __rect: region rect of `__self' to-be returned
872+ * @param: __xor_flags: Flags to xor- toggle in GFX contexts created on `return'.
873+ * These flags are NOT applied to `__rect', but they still
874+ * allow you to create region buffers that will appear to be
875+ * natively rotated in `struct video_gfx' contexts. Only the
876+ * following flags *should* be used here. All other flags can
877+ * still be used, but many not necessarily produce expected
878+ * results:
879+ * - VIDEO_GFX_F_XMIRROR
880+ * - VIDEO_GFX_F_YMIRROR
881+ * - VIDEO_GFX_F_XYSWAP
882+ * @return: * : The newly created region buffer
883+ * @return: NULL: [errno=ENOMEM] Insufficient memory
884+ * @return: NULL: [errno=*] Failed to create region for some other reason */
885+ typedef __ATTR_WUNUSED_T __ATTR_INOUT_T (1 ) __ATTR_IN_T(2 ) __REF struct video_buffer *
886+ (LIBVIDEO_GFX_CC *PVIDEO_BUFFER_REGION)(struct video_buffer *__restrict __self,
887+ struct video_rect const *__restrict __rect,
888+ gfx_flag_t __xor_flags);
889+ #ifdef LIBVIDEO_GFX_WANT_PROTOTYPES
890+ LIBVIDEO_GFX_DECL __ATTR_WUNUSED __ATTR_INOUT (1 ) __ATTR_IN(2 ) __REF struct video_buffer *LIBVIDEO_GFX_CC
891+ video_buffer_region(struct video_buffer *__restrict __self,
892+ struct video_rect const *__restrict __rect,
893+ gfx_flag_t __xor_flags);
894+ #endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
895+
896+
897+
898+
788899/* Return a video buffer that will always (forcefully) re-return `__self'
789900 * whenever a GFX context is requested. Additionally, video locks will fail
790901 * when pixels represented by `__self' cannot represented as a video lock
0 commit comments