@@ -74,13 +74,9 @@ struct video_lock {
7474
7575struct video_regionlock {
7676 /* WARNING: DO NOT MODIFY ANYTHING HERE BEFORE `video_buffer_unlockregion()' */
77- struct video_lock vrl_lock; /* [out] Underlying video lock */
78- video_coord_t vrl_xbas; /* [out] X-offset added to start of every scanline */
79-
80- video_coord_t _vrl_xmin; /* [in][const] Region starting X pixel coord */
81- video_coord_t _vrl_ymin; /* [in][const] Region starting Y pixel coord */
82- video_dim_t _vrl_xdim; /* [in][const] Region X dimension */
83- video_dim_t _vrl_ydim; /* [in][const] Region Y dimension */
77+ struct video_lock vrl_lock; /* [out] Underlying video lock */
78+ video_coord_t vrl_xbas; /* [out] X-offset added to start of every scanline */
79+ struct video_crect _vrl_rect; /* [in][const] Region */
8480};
8581
8682struct video_buffer_ops {
@@ -143,12 +139,12 @@ struct video_buffer_ops {
143139 *
144140 * Also: this function may succeed in cases where `vi_rlock' fails.
145141 *
146- * @assume(__lock->_vrl_xdim > 0);
147- * @assume(__lock->_vrl_ydim > 0);
148- * @assume((__lock->_vrl_xmin + __lock->_vrl_xdim ) > __lock->_vrl_xmin );
149- * @assume((__lock->_vrl_ymin + __lock->_vrl_ydim ) > __lock->_vrl_ymin );
150- * @assume((__lock->_vrl_xmin + __lock->_vrl_xdim ) <= __self->vb_xdim);
151- * @assume((__lock->_vrl_ymin + __lock->_vrl_ydim ) <= __self->vb_ydim);
142+ * @assume(__lock->_vrl_rect.vcr_xdim > 0);
143+ * @assume(__lock->_vrl_rect.vcr_ydim > 0);
144+ * @assume((__lock->_vrl_rect.vcr_xmin + __lock->_vrl_rect.vcr_xdim ) > __lock->_vrl_rect.vcr_xmin );
145+ * @assume((__lock->_vrl_rect.vcr_ymin + __lock->_vrl_rect.vcr_ydim ) > __lock->_vrl_rect.vcr_ymin );
146+ * @assume((__lock->_vrl_rect.vcr_xmin + __lock->_vrl_rect.vcr_xdim ) <= __self->vb_xdim);
147+ * @assume((__lock->_vrl_rect.vcr_ymin + __lock->_vrl_rect.vcr_ydim ) <= __self->vb_ydim);
152148 *
153149 * @return: 0: Success
154150 * @return: -1: Error (s.a. `errno') */
@@ -161,12 +157,12 @@ struct video_buffer_ops {
161157 *
162158 * Also: this function may succeed in cases where `vi_wlock' fails.
163159 *
164- * @assume(__lock->_vrl_xdim > 0);
165- * @assume(__lock->_vrl_ydim > 0);
166- * @assume((__lock->_vrl_xmin + __lock->_vrl_xdim ) > __lock->_vrl_xmin );
167- * @assume((__lock->_vrl_ymin + __lock->_vrl_ydim ) > __lock->_vrl_ymin );
168- * @assume((__lock->_vrl_xmin + __lock->_vrl_xdim ) <= __self->vb_xdim);
169- * @assume((__lock->_vrl_ymin + __lock->_vrl_ydim ) <= __self->vb_ydim);
160+ * @assume(__lock->_vrl_rect.vcr_xdim > 0);
161+ * @assume(__lock->_vrl_rect.vcr_ydim > 0);
162+ * @assume((__lock->_vrl_rect.vcr_xmin + __lock->_vrl_rect.vcr_xdim ) > __lock->_vrl_rect.vcr_xmin );
163+ * @assume((__lock->_vrl_rect.vcr_ymin + __lock->_vrl_rect.vcr_ydim ) > __lock->_vrl_rect.vcr_ymin );
164+ * @assume((__lock->_vrl_rect.vcr_xmin + __lock->_vrl_rect.vcr_xdim ) <= __self->vb_xdim);
165+ * @assume((__lock->_vrl_rect.vcr_ymin + __lock->_vrl_rect.vcr_ydim ) <= __self->vb_ydim);
170166 *
171167 * @return: 0: Success
172168 * @return: -1: Error (s.a. `errno') */
@@ -312,12 +308,12 @@ video_buffer_unlockregion(struct video_buffer *__self, struct video_regionlock *
312308#define video_buffer_unlock (self, lock ) \
313309 (*(self)->vb_ops->vi_unlock)(self, lock)
314310#define video_buffer_rlockregion (self, lock, xmin, ymin, xdim, ydim ) \
315- ((lock)->_vrl_xmin = (xmin), (lock)->_vrl_ymin = (ymin), \
316- (lock)->_vrl_xdim = (xdim), (lock)->_vrl_ydim = (ydim), \
311+ ((lock)->_vrl_rect.vcr_xmin = (xmin), (lock)->_vrl_rect.vcr_ymin = (ymin), \
312+ (lock)->_vrl_rect.vcr_xdim = (xdim), (lock)->_vrl_rect.vcr_ydim = (ydim), \
317313 (*(self)->vb_ops->vi_rlockregion)(self, lock))
318314#define video_buffer_wlockregion (self, lock, xmin, ymin, xdim, ydim ) \
319- ((lock)->_vrl_xmin = (xmin), (lock)->_vrl_ymin = (ymin), \
320- (lock)->_vrl_xdim = (xdim), (lock)->_vrl_ydim = (ydim), \
315+ ((lock)->_vrl_rect.vcr_xmin = (xmin), (lock)->_vrl_rect.vcr_ymin = (ymin), \
316+ (lock)->_vrl_rect.vcr_xdim = (xdim), (lock)->_vrl_rect.vcr_ydim = (ydim), \
321317 (*(self)->vb_ops->vi_wlockregion)(self, lock))
322318#define video_buffer_unlockregion (self, lock ) \
323319 (*(self)->vb_ops->vi_unlockregion)(self, lock)
@@ -612,6 +608,54 @@ video_buffer_fromgfx(struct video_gfx const *__restrict __self);
612608#endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
613609
614610
611+ /* Create a wrapper video buffer for `__self' that can only ever be used to access
612+ * the intersection of pixels from `__rect' and `__self' (trying a GFX context will
613+ * always start out with the I/O rect set to "__rect", but the clip rect still set
614+ * to the buffer's base dimensions, and trying to lock OOB regions always fails)
615+ *
616+ * NOTE: Starting coords in `__rect' are allowed to be negative, and its dimensions
617+ * are allowed to be greater than those of `__self', too!
618+ *
619+ * `video_buffer_region_revocable()' does the same, but the returned video buffer
620+ * is also "revocable" (s.a. `video_buffer_region_revoke()'), meaning it can be
621+ * detached from the original buffer (and turned into a no-op) at any point in time
622+ * (blocking if a video lock is held in `video_buffer_region_revoke()').
623+ *
624+ * @return: * : The wrapper video buffer
625+ * @return: NULL: Failed to create video buffer (s.a. `errno') */
626+ typedef __ATTR_WUNUSED_T __ATTR_INOUT_T (1 ) __ATTR_IN_T(2 ) __REF struct video_buffer *
627+ (LIBVIDEO_GFX_CC *PVIDEO_BUFFER_REGION)(struct video_buffer *__restrict __self,
628+ struct video_rect const *__restrict __rect);
629+ typedef __ATTR_WUNUSED_T __ATTR_INOUT_T (1 ) __ATTR_IN_T(2 ) __REF struct video_buffer *
630+ (LIBVIDEO_GFX_CC *PVIDEO_BUFFER_REGION_REVOCABLE)(struct video_buffer *__restrict __self,
631+ struct video_rect const *__restrict __rect);
632+ #ifdef LIBVIDEO_GFX_WANT_PROTOTYPES
633+ LIBVIDEO_GFX_DECL __ATTR_WUNUSED __ATTR_INOUT (1 ) __ATTR_IN(2 ) __REF struct video_buffer *LIBVIDEO_GFX_CC
634+ video_buffer_region(struct video_buffer *__restrict __self,
635+ struct video_rect const *__restrict __rect);
636+ LIBVIDEO_GFX_DECL __ATTR_WUNUSED __ATTR_INOUT (1 ) __ATTR_IN(2 ) __REF struct video_buffer *LIBVIDEO_GFX_CC
637+ video_buffer_region_revocable(struct video_buffer *__restrict __self,
638+ struct video_rect const *__restrict __rect);
639+ #endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
640+
641+
642+ /* Revoke access to the underlying video buffer, given a video
643+ * buffer that was returned by `video_buffer_region_revocable()'.
644+ * If the buffer had already been revoked, this is a no-op.
645+ *
646+ * >> DO NOT CALL THIS FUNCTION FOR BUFFERS OBTAINED FROM SOMETHING
647+ * >> OTHER THAN `video_buffer_region_revocable()' !!!
648+ *
649+ * @return: * : Always re-returns `__self' */
650+ typedef __ATTR_INOUT_T (1 ) struct video_buffer *
651+ (LIBVIDEO_GFX_CC *PVIDEO_BUFFER_REGION_REVOKE)(struct video_buffer *__restrict __self);
652+ #ifdef LIBVIDEO_GFX_WANT_PROTOTYPES
653+ LIBVIDEO_GFX_DECL __ATTR_INOUT (1 ) struct video_buffer *LIBVIDEO_GFX_CC
654+ video_buffer_region_revoke(struct video_buffer *__restrict __self);
655+ #endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
656+
657+
658+
615659/* Various functions for opening a file/stream/blob as an image file.
616660 * The actual file format is auto-detected, and supported formats depend
617661 * on installed 3rd party libraries. By default, BMP and PNG is supported. */
0 commit comments