Skip to content

Commit 9fd54c2

Browse files
committed
Fix various bugs within the compositor
1 parent 0da239d commit 9fd54c2

File tree

4 files changed

+206
-111
lines changed

4 files changed

+206
-111
lines changed

kos/include/libvideo/codec/rectutils.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424

2525
#include <__stdinc.h>
2626

27-
#include <hybrid/__minmax.h>
2827
#include <hybrid/__assert.h>
28+
#include <hybrid/__minmax.h>
29+
#include <hybrid/__overflow.h>
2930

3031
#include <bits/types.h>
3132

@@ -82,6 +83,30 @@ video_rect_intersect(struct video_rect const *__restrict a,
8283
return 0;
8384
}
8485

86+
/* Same as `video_rect_intersect()', but safely handles overflow in "b" */
87+
__LOCAL __ATTR_WUNUSED __ATTR_IN(1) __ATTR_IN(2) __ATTR_OUT(3) __BOOL LIBVIDEO_CODEC_CC
88+
video_rect_intersect_overflow_in_b(struct video_rect const *__restrict a,
89+
struct video_rect const *__restrict b,
90+
struct video_rect *__restrict intersect) {
91+
video_offset_t a_xend = video_rect_getxend(a);
92+
video_offset_t a_yend = video_rect_getyend(a);
93+
video_offset_t b_xend, b_yend;
94+
video_offset_t intersect_xend = __hybrid_min(a_xend, b_xend);
95+
video_offset_t intersect_yend = __hybrid_min(a_yend, b_yend);
96+
if (__hybrid_overflow_sadd(video_rect_getxmin(b), video_rect_getxdim(b), &b_xend))
97+
b_xend = VIDEO_OFFSET_MAX;
98+
if (__hybrid_overflow_sadd(video_rect_getymin(b), video_rect_getydim(b), &b_yend))
99+
b_yend = VIDEO_OFFSET_MAX;
100+
video_rect_setxmin(intersect, __hybrid_max(video_rect_getxmin(a), video_rect_getxmin(b)));
101+
video_rect_setymin(intersect, __hybrid_max(video_rect_getymin(a), video_rect_getymin(b)));
102+
if (video_rect_getxmin(intersect) < intersect_xend && video_rect_getymin(intersect) < intersect_yend) {
103+
video_rect_setxend(intersect, intersect_xend);
104+
video_rect_setyend(intersect, intersect_yend);
105+
return 1;
106+
}
107+
return 0;
108+
}
109+
85110

86111
/* Update `__union' by adding `__addme' */
87112
__LOCAL __ATTR_INOUT(1) __ATTR_IN(2) void LIBVIDEO_CODEC_CC

kos/src/apps/showpic/main.c

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ do_showpic(struct video_buffer *screen,
538538
int main(int argc, char *argv[]) {
539539
REF struct video_font *font;
540540
REF struct screen_buffer *screen;
541-
REF struct video_display *bdisplay = NULL;
541+
REF struct video_display *display = NULL;
542542
REF struct video_buffer *bscreen;
543543
REF struct video_buffer *frame;
544544
REF struct video_anim *anim;
@@ -575,68 +575,70 @@ int main(int argc, char *argv[]) {
575575
bscreen = screen_buffer_asvideo(screen);
576576
#endif
577577

578-
#if 0
578+
#if 1
579579
{
580580
struct video_window_position position;
581-
REF struct video_display *display;
581+
REF struct video_display *temp_display;
582582
REF struct video_buffer *buffer;
583583
REF struct video_compositor *compositor;
584584
REF struct video_window *window1;
585585
REF struct video_window *window2;
586586
/* TODO: This is the wrong way around -- "screen_buffer" shouldn't exist, and
587587
* should actually be "video_monitor", which extends "video_display". */
588-
display = video_display_forbuffer(bscreen);
589-
if unlikely(!display)
588+
temp_display = video_display_forbuffer(bscreen);
589+
if unlikely(!temp_display)
590590
err(EXIT_FAILURE, "Failed to wrap screen in display");
591-
compositor = video_compositor_create(display, VIDEO_COMPOSITOR_FEAT_ALL, VIDEO_COLOR_AQUA);
591+
compositor = video_compositor_create(temp_display, VIDEO_COMPOSITOR_FEAT_ALL, VIDEO_COLOR_AQUA);
592592
if unlikely(!compositor)
593593
err(EXIT_FAILURE, "Failed to allocate compositor");
594594

595595
position.vwp_over = VIDEO_WINDOW_MOVE_OVER__FOREGROUND;
596596
position.vwp_attr.vwa_flags = VIDEO_WINDOW_F_PASSTHRU;
597-
position.vwp_attr.vwa_rect.vr_xmin = 10;
598-
position.vwp_attr.vwa_rect.vr_ymin = 10;
599-
position.vwp_attr.vwa_rect.vr_xdim = 400;
600-
position.vwp_attr.vwa_rect.vr_ydim = 400;
597+
position.vwp_attr.vwa_rect.vr_xmin = 80;
598+
position.vwp_attr.vwa_rect.vr_ymin = 80;
599+
position.vwp_attr.vwa_rect.vr_xdim = bscreen->vb_xdim - 160;
600+
position.vwp_attr.vwa_rect.vr_ydim = bscreen->vb_ydim - 160;
601601
window1 = video_compositor_newwindow(compositor, &position, NULL);
602602
if unlikely(!window1)
603603
err(EXIT_FAILURE, "Failed to allocate window1");
604604

605-
/* Render some stuff to the first window */
606-
buffer = video_window_getbuffer(window1);
605+
/* Create a second (small) window to interact with the first (big) one */
606+
position.vwp_over = VIDEO_WINDOW_MOVE_OVER__FOREGROUND;
607+
position.vwp_attr.vwa_flags = VIDEO_WINDOW_F_PASSTHRU /*| VIDEO_WINDOW_F_ALPHA*/;
608+
position.vwp_attr.vwa_rect.vr_xmin = 10;
609+
position.vwp_attr.vwa_rect.vr_ymin = 10;
610+
position.vwp_attr.vwa_rect.vr_xdim = 200;
611+
position.vwp_attr.vwa_rect.vr_ydim = 200;
612+
window2 = video_compositor_newwindow(compositor, &position, NULL);
613+
if unlikely(!window2)
614+
err(EXIT_FAILURE, "Failed to allocate window2");
615+
616+
/* Render some stuff to the second window */
617+
buffer = video_window_getbuffer(window2);
607618
if unlikely(!buffer)
608-
err(EXIT_FAILURE, "Failed to get screen from window1");
619+
err(EXIT_FAILURE, "Failed to get screen from window2");
609620
{
610-
struct video_gfx window1_gfx;
621+
struct video_gfx window2_gfx;
611622
video_color_t colors[2][2];
612-
video_buffer_getgfx(buffer, &window1_gfx,
623+
video_buffer_getgfx(buffer, &window2_gfx,
613624
GFX_BLENDMODE_OVERRIDE,
614625
VIDEO_GFX_F_NORMAL, 0);
615-
colors[0][0] = VIDEO_COLOR_RGB(0xff, 0, 0);
616-
colors[0][1] = VIDEO_COLOR_RGB(0, 0xff, 0);
617-
colors[1][0] = VIDEO_COLOR_RGB(0, 0, 0xff);
618-
colors[1][1] = VIDEO_COLOR_RGB(0xff, 0xff, 0xff);
619-
video_gfx_gradient(&window1_gfx, 0, 0,
620-
video_gfx_getclipw(&window1_gfx),
621-
video_gfx_getcliph(&window1_gfx),
626+
colors[0][0] = VIDEO_COLOR_RGBA(0xff, 0, 0, 0xff);
627+
colors[0][1] = VIDEO_COLOR_RGBA(0, 0xff, 0, 0xff);
628+
colors[1][0] = VIDEO_COLOR_RGBA(0, 0, 0xff, 0xff);
629+
colors[1][1] = VIDEO_COLOR_RGBA(0xff, 0xff, 0xff, 0xff);
630+
video_gfx_gradient(&window2_gfx, 0, 0,
631+
video_gfx_getclipw(&window2_gfx),
632+
video_gfx_getcliph(&window2_gfx),
622633
colors);
634+
video_window_updaterect(window2, &RECT_FULL);
623635
}
624636

625-
position.vwp_over = VIDEO_WINDOW_MOVE_OVER__BACKGROUND;
626-
position.vwp_attr.vwa_flags = VIDEO_WINDOW_F_PASSTHRU;
627-
position.vwp_attr.vwa_rect.vr_xmin = 80;
628-
position.vwp_attr.vwa_rect.vr_ymin = 80;
629-
position.vwp_attr.vwa_rect.vr_xdim = bscreen->vb_xdim - 160;
630-
position.vwp_attr.vwa_rect.vr_ydim = bscreen->vb_ydim - 160;
631-
window2 = video_compositor_newwindow(compositor, &position, NULL);
632-
if unlikely(!window2)
633-
err(EXIT_FAILURE, "Failed to allocate window2");
634-
635-
/* Use the second window as output for the main program */
636-
bdisplay = video_window_asdisplay(window2);
637-
bscreen = video_window_getbuffer(window2);
637+
/* Use the first window as output for the main program below... */
638+
display = video_window_asdisplay(window1);
639+
bscreen = video_window_getbuffer(window1);
638640
if unlikely(!bscreen)
639-
err(EXIT_FAILURE, "Failed to get screen from window2");
641+
err(EXIT_FAILURE, "Failed to get screen from window1");
640642
}
641643
#endif
642644

@@ -682,8 +684,11 @@ int main(int argc, char *argv[]) {
682684

683685
/* Render frame */
684686
do_showpic(bscreen, frame, font, argv[1], &frame_info);
685-
if (bdisplay)
686-
video_display_updaterect(bdisplay, &RECT_FULL);
687+
if (display) {
688+
syslog(LOG_DEBUG, "BEGIN: video_display_updaterect()\n");
689+
video_display_updaterect(display, &RECT_FULL);
690+
syslog(LOG_DEBUG, "END: video_display_updaterect()\n");
691+
}
687692
screen_buffer_updaterect(screen, &CRECT_FULL);
688693

689694
/* Load next frame as part of render delay */

0 commit comments

Comments
 (0)