mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-12 09:31:04 +00:00
Replace custom region implementation with pixman_region32_t
pixman_region32_t is an efficient well tested region implementation (its the one used in X) that we already depend on via pixman and use in some places. No need to have a custom region implementation.
This commit is contained in:
parent
8f912e4917
commit
98dde80ed3
@ -171,13 +171,23 @@ InfoLayer::InfoLayer()
|
||||
|
||||
void InfoLayer::draw_info(const QRegion& dest_region, RedDrawable& dest)
|
||||
{
|
||||
for (int i = 0; i < (int)dest_region.num_rects; i++) {
|
||||
SpiceRect* r = &dest_region.rects[i];
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)&dest_region, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
|
||||
/* is rect inside sticky region or info region? */
|
||||
if (_sticky_on && rect_intersects(*r, _sticky_rect)) {
|
||||
dest.blend_pixels(_sticky_pixmap, r->left - _sticky_pos.x, r->top - _sticky_pos.y, *r);
|
||||
if (_sticky_on && rect_intersects(r, _sticky_rect)) {
|
||||
dest.blend_pixels(_sticky_pixmap, r.left - _sticky_pos.x, r.top - _sticky_pos.y, r);
|
||||
} else {
|
||||
dest.blend_pixels(_info_pixmap, r->left - _info_pos.x, r->top - _info_pos.y, *r);
|
||||
dest.blend_pixels(_info_pixmap, r.left - _info_pos.x, r.top - _info_pos.y, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "region.h"
|
||||
#include "cairo.h"
|
||||
#include <spice/protocol.h>
|
||||
#include "cache.hpp"
|
||||
@ -36,8 +37,6 @@ enum CanvasType {
|
||||
CANVAS_TYPE_GDI,
|
||||
};
|
||||
|
||||
struct QRegion;
|
||||
|
||||
class PixmapCacheTreat {
|
||||
public:
|
||||
static inline pixman_image_t *get(pixman_image_t *surf)
|
||||
|
||||
@ -434,16 +434,26 @@ void CursorChannel::remove_cursor()
|
||||
|
||||
void CursorChannel::copy_pixels(const QRegion& dest_region, RedDrawable& dest_dc)
|
||||
{
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
Lock lock(_update_lock);
|
||||
|
||||
if (!_cursor_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)dest_region.num_rects; i++) {
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)&dest_region, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
ASSERT(_cursor && _cursor->get_opaque());
|
||||
((NaitivCursor*)_cursor->get_opaque())->draw(dest_dc, _cursor_rect.left, _cursor_rect.top,
|
||||
dest_region.rects[i]);
|
||||
r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1025,19 +1025,33 @@ void GUI::update_layer_area()
|
||||
|
||||
void GUI::copy_pixels(const QRegion& dest_region, RedDrawable& dest)
|
||||
{
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
if (region_is_empty(&dest_region)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)dest_region.num_rects; i++) {
|
||||
SpiceRect* r = &dest_region.rects[i];
|
||||
_pixmap->copy_pixels(dest, r->left, r->top, *r);
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)&dest_region, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
_pixmap->copy_pixels(dest, r.left, r.top, r);
|
||||
}
|
||||
|
||||
_gui_system->renderGUI();
|
||||
for (int i = 0; i < (int)dest_region.num_rects; i++) {
|
||||
SpiceRect* r = &dest_region.rects[i];
|
||||
dest.copy_pixels(*_pixmap, r->left, r->top, *r);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
dest.copy_pixels(*_pixmap, r.left, r.top, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,9 +68,18 @@ void CCanvas::create_pixmap(int width, int height, RedWindow *win)
|
||||
|
||||
void CCanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
|
||||
{
|
||||
for (int i = 0; i < (int)region.num_rects; i++) {
|
||||
SpiceRect* r = ®ion.rects[i];
|
||||
dest_dc.copy_pixels(*_pixmap, r->left, r->top, *r);
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)®ion, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
dest_dc.copy_pixels(*_pixmap, r.left, r.top, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,9 +69,19 @@ void GCanvas::create_pixmap(int width, int height, RedWindow *win,
|
||||
|
||||
void GCanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
|
||||
{
|
||||
for (int i = 0; i < (int)region.num_rects; i++) {
|
||||
SpiceRect* r = ®ion.rects[i];
|
||||
dest_dc.copy_pixels(*_pixmap, r->left, r->top, *r);
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)®ion, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
|
||||
dest_dc.copy_pixels(*_pixmap, r.left, r.top, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -288,9 +288,18 @@ void RedScreen::detach_layer(ScreenLayer& layer)
|
||||
|
||||
void RedScreen::composit_to_screen(RedDrawable& win_dc, const QRegion& region)
|
||||
{
|
||||
for (int i = 0; i < (int)region.num_rects; i++) {
|
||||
SpiceRect* r = ®ion.rects[i];
|
||||
win_dc.copy_pixels(*_composit_area, r->left, r->top, *r);
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)®ion, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
win_dc.copy_pixels(*_composit_area, r.left, r.top, r);
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,17 +483,40 @@ uint64_t RedScreen::invalidate(const SpiceRect& rect, bool urgent)
|
||||
|
||||
void RedScreen::invalidate(const QRegion ®ion)
|
||||
{
|
||||
SpiceRect *r = region.rects;
|
||||
SpiceRect *end = r + region.num_rects;
|
||||
while (r != end) {
|
||||
invalidate(*r++, false);
|
||||
pixman_box32_t *rects, *end;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)®ion, &num_rects);
|
||||
end = rects + num_rects;
|
||||
|
||||
while (rects != end) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects->x1;
|
||||
r.top = rects->y1;
|
||||
r.right = rects->x2;
|
||||
r.bottom = rects->y2;
|
||||
rects++;
|
||||
|
||||
invalidate(r, false);
|
||||
}
|
||||
}
|
||||
|
||||
inline void RedScreen::erase_background(RedDrawable& dc, const QRegion& composit_rgn)
|
||||
{
|
||||
for (int i = 0; i < (int)composit_rgn.num_rects; i++) {
|
||||
dc.fill_rect(composit_rgn.rects[i], 0);
|
||||
pixman_box32_t *rects;
|
||||
int num_rects;
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)&composit_rgn, &num_rects);
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects[i].x1;
|
||||
r.top = rects[i].y1;
|
||||
r.right = rects[i].x2;
|
||||
r.bottom = rects[i].y2;
|
||||
|
||||
dc.fill_rect(r, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -93,13 +93,26 @@ uint64_t ScreenLayer::invalidate(const SpiceRect& r, bool urgent)
|
||||
|
||||
void ScreenLayer::invalidate(const QRegion& region)
|
||||
{
|
||||
pixman_box32_t *rects, *end;
|
||||
int num_rects;
|
||||
|
||||
if (!_screen) {
|
||||
return;
|
||||
}
|
||||
SpiceRect *r = region.rects;
|
||||
SpiceRect *end = r + region.num_rects;
|
||||
while (r != end) {
|
||||
invalidate_rect(*r++, false);
|
||||
|
||||
rects = pixman_region32_rectangles((pixman_region32_t *)®ion, &num_rects);
|
||||
end = rects + num_rects;
|
||||
|
||||
while (rects != end) {
|
||||
SpiceRect r;
|
||||
|
||||
r.left = rects->x1;
|
||||
r.top = rects->y1;
|
||||
r.right = rects->x2;
|
||||
r.bottom = rects->y2;
|
||||
rects++;
|
||||
|
||||
invalidate_rect(r, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1835,7 +1835,10 @@ public:
|
||||
if (region_is_empty(_region)) {
|
||||
bbox.left = bbox.right = bbox.top = bbox.bottom = 0;
|
||||
} else {
|
||||
bbox = _region->bbox;
|
||||
bbox.left = _region->extents.x1;
|
||||
bbox.top = _region->extents.y1;
|
||||
bbox.right = _region->extents.x2;
|
||||
bbox.bottom = _region->extents.y2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1130,11 +1130,14 @@ void canvas_put_image(CairoCanvas *canvas, const SpiceRect *dest, const uint8_t
|
||||
cairo_save(cairo);
|
||||
|
||||
if (clip) {
|
||||
const SpiceRect *now = clip->rects;
|
||||
const SpiceRect *end = clip->rects + clip->num_rects;
|
||||
int num_rects;
|
||||
pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip,
|
||||
&num_rects);
|
||||
const pixman_box32_t *now = rects;
|
||||
const pixman_box32_t *end = rects + num_rects;
|
||||
for (; now < end; now++) {
|
||||
cairo_rectangle(cairo, now->left, now->top, now->right - now->left,
|
||||
now->bottom - now->top);
|
||||
cairo_rectangle(cairo, now->x1, now->y1, now->x2 - now->x1,
|
||||
now->y2 - now->y1);
|
||||
}
|
||||
cairo_clip(cairo);
|
||||
}
|
||||
@ -2137,23 +2140,16 @@ void canvas_read_bits(CairoCanvas *canvas, uint8_t *dest, int dest_stride, const
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_group_start(CairoCanvas *canvas, int n_clip_rects, SpiceRect *clip_rects)
|
||||
void canvas_group_start(CairoCanvas *canvas, QRegion *region)
|
||||
{
|
||||
pixman_region32_t dest_region;
|
||||
|
||||
pixman_region32_fini(&canvas->canvas_region);
|
||||
spice_pixman_region32_init_rects(&canvas->canvas_region,
|
||||
clip_rects, n_clip_rects);
|
||||
|
||||
pixman_region32_init_rect(&dest_region,
|
||||
0, 0,
|
||||
pixman_image_get_width(canvas->image),
|
||||
pixman_image_get_height(canvas->image));
|
||||
|
||||
/* Make sure we always clip to canvas size */
|
||||
pixman_region32_intersect(&canvas->canvas_region, &canvas->canvas_region, &dest_region);
|
||||
pixman_region32_init_rect(&canvas->canvas_region,
|
||||
0, 0,
|
||||
pixman_image_get_width (canvas->image),
|
||||
pixman_image_get_height (canvas->image));
|
||||
|
||||
pixman_region32_fini(&dest_region);
|
||||
pixman_region32_intersect(&canvas->canvas_region, &canvas->canvas_region, region);
|
||||
}
|
||||
|
||||
void canvas_group_end(CairoCanvas *canvas)
|
||||
|
||||
@ -52,7 +52,7 @@ void canvas_put_image(CairoCanvas *canvas, const SpiceRect *dest, const uint8_t
|
||||
#endif
|
||||
void canvas_clear(CairoCanvas *canvas);
|
||||
void canvas_read_bits(CairoCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
|
||||
void canvas_group_start(CairoCanvas *canvas, int n_clip_rects, SpiceRect *clip_rects);
|
||||
void canvas_group_start(CairoCanvas *canvas, QRegion *region);
|
||||
void canvas_group_end(CairoCanvas *canvas);
|
||||
void canvas_set_addr_delta(CairoCanvas *canvas, SPICE_ADDRESS delta);
|
||||
#ifdef CAIRO_CANVAS_ACCESS_TEST
|
||||
|
||||
@ -164,6 +164,13 @@ static GLCPath get_path(GLCanvas *canvas, void *addr)
|
||||
(dest)->height = (src)->bottom - (src)->top; \
|
||||
}
|
||||
|
||||
#define SET_GLC_BOX(dest, src) { \
|
||||
(dest)->x = (src)->x1; \
|
||||
(dest)->y = (src)->y1; \
|
||||
(dest)->width = (src)->x2 - (src)->x1; \
|
||||
(dest)->height = (src)->y2 - (src)->y1; \
|
||||
}
|
||||
|
||||
static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
|
||||
{
|
||||
GLCRect rect;
|
||||
@ -706,14 +713,21 @@ void gl_canvas_read_pixels(GLCanvas *canvas, uint8_t *dest, int dest_stride, con
|
||||
glc_read_pixels(canvas->glc, area->left, area->top, &image);
|
||||
}
|
||||
|
||||
void gl_canvas_set_top_mask(GLCanvas *canvas, int num_rect, const SpiceRect *rects)
|
||||
void gl_canvas_set_top_mask(GLCanvas *canvas, QRegion *region)
|
||||
{
|
||||
GLCRect *glc_rects = (GLCRect *)malloc(num_rect * sizeof(GLCRect));
|
||||
GLCRect *now = glc_rects;
|
||||
GLCRect *end = glc_rects + num_rect;
|
||||
GLCRect *glc_rects;
|
||||
GLCRect *now, *end;
|
||||
int num_rect;
|
||||
pixman_box32_t *rects;
|
||||
|
||||
rects = pixman_region32_rectangles(region, &num_rect);
|
||||
|
||||
glc_rects = (GLCRect *)malloc(num_rect * sizeof(GLCRect));
|
||||
now = glc_rects;
|
||||
end = glc_rects + num_rect;
|
||||
|
||||
for (; now < end; now++, rects++) {
|
||||
SET_GLC_RECT(now, rects);
|
||||
SET_GLC_BOX(now, rects);
|
||||
}
|
||||
glc_mask_rects(canvas->glc, num_rect, glc_rects, GLC_MASK_B);
|
||||
|
||||
@ -733,15 +747,18 @@ void gl_canvas_put_image(GLCanvas *canvas, const SpiceRect *dest, const uint8_t
|
||||
glc_clip_reset(canvas->glc);
|
||||
|
||||
if (clip) {
|
||||
int num_rects;
|
||||
pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip,
|
||||
&num_rects);
|
||||
GLCRect rect;
|
||||
if (clip->num_rects == 0) {
|
||||
if (num_rects == 0) {
|
||||
rect.x = rect.y = rect.width = rect.height = 0;
|
||||
glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
|
||||
} else {
|
||||
SET_GLC_RECT(&rect, clip->rects);
|
||||
SET_GLC_BOX(&rect, rects);
|
||||
glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET);
|
||||
for (i = 1; i < clip->num_rects; i++) {
|
||||
SET_GLC_RECT(&rect, clip->rects + i);
|
||||
for (i = 1; i < num_rects; i++) {
|
||||
SET_GLC_BOX(&rect, rects + i);
|
||||
glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ void gl_canvas_put_image(GLCanvas *canvas, const SpiceRect *dest, const uint8_t
|
||||
|
||||
void gl_canvas_clear(GLCanvas *canvas);
|
||||
|
||||
void gl_canvas_set_top_mask(GLCanvas *canvas, int num_rect, const SpiceRect *rects);
|
||||
void gl_canvas_set_top_mask(GLCanvas *canvas, QRegion *region);
|
||||
void gl_canvas_clear_top_mask(GLCanvas *canvas);
|
||||
|
||||
#ifdef CAIRO_CANVAS_ACCESS_TEST
|
||||
|
||||
1440
common/region.c
1440
common/region.c
File diff suppressed because it is too large
Load Diff
@ -21,20 +21,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <spice/draw.h>
|
||||
#include <pixman_utils.h>
|
||||
|
||||
#define REGION_USE_IMPROVED
|
||||
|
||||
#define RECTS_BUF_SIZE 4
|
||||
|
||||
typedef struct QRegion {
|
||||
uint32_t num_rects;
|
||||
SpiceRect bbox;
|
||||
SpiceRect *rects;
|
||||
uint32_t rects_size;
|
||||
SpiceRect buf[RECTS_BUF_SIZE];
|
||||
} QRegion;
|
||||
|
||||
#ifdef REGION_USE_IMPROVED
|
||||
typedef pixman_region32_t QRegion;
|
||||
|
||||
#define REGION_TEST_LEFT_EXCLUSIVE (1 << 0)
|
||||
#define REGION_TEST_RIGHT_EXCLUSIVE (1 << 1)
|
||||
@ -42,16 +31,13 @@ typedef struct QRegion {
|
||||
#define REGION_TEST_ALL \
|
||||
(REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED)
|
||||
|
||||
#endif
|
||||
|
||||
void region_init(QRegion *rgn);
|
||||
void region_clear(QRegion *rgn);
|
||||
void region_destroy(QRegion *rgn);
|
||||
void region_clone(QRegion *dest, const QRegion *src);
|
||||
SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects);
|
||||
|
||||
#ifdef REGION_USE_IMPROVED
|
||||
int region_test(const QRegion *rgn, const QRegion *other_rgn, int query);
|
||||
#endif
|
||||
int region_is_valid(const QRegion *rgn);
|
||||
int region_is_empty(const QRegion *rgn);
|
||||
int region_is_equal(const QRegion *rgn1, const QRegion *rgn2);
|
||||
|
||||
@ -427,7 +427,8 @@ typedef struct StreamClipItem {
|
||||
int refs;
|
||||
StreamAgent *stream_agent;
|
||||
int clip_type;
|
||||
QRegion region;
|
||||
SpiceRect *rects;
|
||||
uint32_t n_rects;
|
||||
} StreamClipItem;
|
||||
|
||||
typedef struct RedCompressBuf RedCompressBuf;
|
||||
@ -826,7 +827,8 @@ typedef struct UpgradeItem {
|
||||
PipeItem base;
|
||||
int refs;
|
||||
Drawable *drawable;
|
||||
QRegion region;
|
||||
SpiceRect *rects;
|
||||
uint32_t n_rects;
|
||||
} UpgradeItem;
|
||||
|
||||
typedef void (*draw_fill_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
|
||||
@ -843,7 +845,7 @@ typedef void (*draw_invers_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, Sp
|
||||
typedef void (*draw_transparent_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
|
||||
typedef void (*draw_alpha_blend_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
|
||||
typedef void (*read_pixels_t)(void *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
|
||||
typedef void (*set_top_mask_t)(void *canvas, int num_rect, const SpiceRect *rects);
|
||||
typedef void (*set_top_mask_t)(void *canvas, QRegion *region);
|
||||
typedef void (*clear_top_mask_t)(void *canvas);
|
||||
typedef void (*validate_area_t)(void *canvas, int32_t stride, uint8_t *line_0, const SpiceRect *area);
|
||||
typedef void (*destroy_t)(void *canvas);
|
||||
@ -1306,10 +1308,10 @@ static void show_draw_item(RedWorker *worker, DrawItem *draw_item, const char *p
|
||||
}
|
||||
printf("effect %d bbox(%d %d %d %d)\n",
|
||||
draw_item->effect,
|
||||
draw_item->base.rgn.bbox.top,
|
||||
draw_item->base.rgn.bbox.left,
|
||||
draw_item->base.rgn.bbox.bottom,
|
||||
draw_item->base.rgn.bbox.right);
|
||||
draw_item->base.rgn.extents.x1,
|
||||
draw_item->base.rgn.extents.y1,
|
||||
draw_item->base.rgn.extents.x2,
|
||||
draw_item->base.rgn.extents.y2);
|
||||
}
|
||||
|
||||
static inline void red_pipe_item_init(PipeItem *item, int type)
|
||||
@ -1428,7 +1430,7 @@ static void release_upgrade_item(RedWorker* worker, UpgradeItem *item)
|
||||
{
|
||||
if (!--item->refs) {
|
||||
release_drawable(worker, item->drawable);
|
||||
region_destroy(&item->region);
|
||||
free(item->rects);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
@ -1904,13 +1906,13 @@ static inline void __exclude_region(RedWorker *worker, TreeItem *item, QRegion *
|
||||
|
||||
if (draw->shadow) {
|
||||
Shadow *shadow;
|
||||
int32_t x = item->rgn.bbox.left;
|
||||
int32_t y = item->rgn.bbox.top;
|
||||
int32_t x = item->rgn.extents.x1;
|
||||
int32_t y = item->rgn.extents.y1;
|
||||
|
||||
region_exclude(&draw->base.rgn, &and_rgn);
|
||||
shadow = draw->shadow;
|
||||
region_offset(&and_rgn, shadow->base.rgn.bbox.left - x,
|
||||
shadow->base.rgn.bbox.top - y);
|
||||
region_offset(&and_rgn, shadow->base.rgn.extents.x1 - x,
|
||||
shadow->base.rgn.extents.y1 - y);
|
||||
region_exclude(&shadow->base.rgn, &and_rgn);
|
||||
region_and(&and_rgn, &shadow->on_hold);
|
||||
if (!region_is_empty(&and_rgn)) {
|
||||
@ -2295,11 +2297,13 @@ static void push_stream_clip_by_drawable(DisplayChannel* channel, StreamAgent *a
|
||||
}
|
||||
|
||||
if (drawable->qxl_drawable->clip.type == SPICE_CLIP_TYPE_NONE) {
|
||||
region_init(&item->region);
|
||||
item->n_rects = 0;
|
||||
item->rects = NULL;
|
||||
item->clip_type = SPICE_CLIP_TYPE_NONE;
|
||||
} else {
|
||||
item->clip_type = SPICE_CLIP_TYPE_RECTS;
|
||||
region_clone(&item->region, &drawable->tree_item.base.rgn);
|
||||
item->rects = region_dup_rects(&drawable->tree_item.base.rgn,
|
||||
&item->n_rects);
|
||||
}
|
||||
red_pipe_add((RedChannel*)channel, (PipeItem *)item);
|
||||
}
|
||||
@ -2311,7 +2315,8 @@ static void push_stream_clip(DisplayChannel* channel, StreamAgent *agent)
|
||||
PANIC("alloc failed");
|
||||
}
|
||||
item->clip_type = SPICE_CLIP_TYPE_RECTS;
|
||||
region_clone(&item->region, &agent->vis_region);
|
||||
item->rects = region_dup_rects(&agent->vis_region,
|
||||
&item->n_rects);
|
||||
red_pipe_add((RedChannel*)channel, (PipeItem *)item);
|
||||
}
|
||||
|
||||
@ -2319,7 +2324,9 @@ static void red_display_release_stream_clip(DisplayChannel* channel, StreamClipI
|
||||
{
|
||||
if (!--item->refs) {
|
||||
red_display_release_stream(channel, item->stream_agent);
|
||||
region_destroy(&item->region);
|
||||
if (item->rects) {
|
||||
free(item->rects);
|
||||
}
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
@ -2387,7 +2394,8 @@ static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *strea
|
||||
red_pipe_item_init(&upgrade_item->base, PIPE_ITEM_TYPE_UPGRADE);
|
||||
upgrade_item->drawable = stream->current;
|
||||
upgrade_item->drawable->refs++;
|
||||
region_clone(&upgrade_item->region, &upgrade_item->drawable->tree_item.base.rgn);
|
||||
upgrade_item->rects = region_dup_rects(&upgrade_item->drawable->tree_item.base.rgn,
|
||||
&upgrade_item->n_rects);
|
||||
red_pipe_add((RedChannel *)channel, &upgrade_item->base);
|
||||
}
|
||||
red_detach_stream(worker, stream);
|
||||
@ -2404,7 +2412,8 @@ static inline void red_stop_stream_gracefully(RedWorker *worker, Stream *stream)
|
||||
red_pipe_item_init(&item->base, PIPE_ITEM_TYPE_UPGRADE);
|
||||
item->drawable = stream->current;
|
||||
item->drawable->refs++;
|
||||
region_clone(&item->region, &item->drawable->tree_item.base.rgn);
|
||||
item->rects = region_dup_rects(&item->drawable->tree_item.base.rgn,
|
||||
&item->n_rects);
|
||||
red_pipe_add((RedChannel *)worker->display_channel, &item->base);
|
||||
}
|
||||
}
|
||||
@ -4304,8 +4313,7 @@ static void red_draw_drawable(RedWorker *worker, Drawable *drawable)
|
||||
#ifdef UPDATE_AREA_BY_TREE
|
||||
//todo: add need top mask flag
|
||||
worker->draw_funcs.set_top_mask(worker->surface.context.canvas,
|
||||
drawable->tree_item.base.rgn.num_rects,
|
||||
drawable->tree_item.base.rgn.rects);
|
||||
&drawable->tree_item.base.rgn);
|
||||
#endif
|
||||
red_draw_qxl_drawable(worker, drawable);
|
||||
#ifdef UPDATE_AREA_BY_TREE
|
||||
@ -6980,8 +6988,8 @@ static void red_display_send_upgrade(DisplayChannel *display_channel, UpgradeIte
|
||||
copy->base.box = qxl_drawable->bbox;
|
||||
copy->base.clip.type = SPICE_CLIP_TYPE_RECTS;
|
||||
copy->base.clip.data = channel->send_data.header.size;
|
||||
add_buf(channel, BUF_TYPE_RAW, &item->region.num_rects, sizeof(uint32_t), 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, item->region.rects, sizeof(SpiceRect) * item->region.num_rects, 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, item->rects, sizeof(SpiceRect) * item->n_rects, 0, 0);
|
||||
copy->data = qxl_drawable->u.copy;
|
||||
fill_bits(display_channel, ©->data.src_bitmap, item->drawable);
|
||||
|
||||
@ -7046,9 +7054,8 @@ static void red_display_send_stream_clip(DisplayChannel *display_channel,
|
||||
} else {
|
||||
ASSERT(stream_clip->clip.type == SPICE_CLIP_TYPE_RECTS);
|
||||
stream_clip->clip.data = channel->send_data.header.size;
|
||||
add_buf(channel, BUF_TYPE_RAW, &item->region.num_rects, sizeof(uint32_t), 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, item->region.rects,
|
||||
item->region.num_rects * sizeof(SpiceRect), 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, &item->n_rects, sizeof(uint32_t), 0, 0);
|
||||
add_buf(channel, BUF_TYPE_RAW, item->rects, item->n_rects * sizeof(SpiceRect), 0, 0);
|
||||
}
|
||||
display_begin_send_massage(display_channel, item);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user