Skip to content
Commits on Source (16)
......@@ -143,14 +143,15 @@ weston_view_dirty_paint_nodes(struct weston_view *view)
}
static void
weston_surface_dirty_paint_nodes(struct weston_surface *surface)
weston_surface_dirty_paint_nodes(struct weston_surface *surface,
enum paint_node_status status)
{
struct weston_paint_node *node;
wl_list_for_each(node, &surface->paint_node_list, surface_link) {
assert(node->surface == surface);
node->status |= PAINT_NODE_VIEW_DIRTY;
node->status |= status;
}
}
......@@ -186,6 +187,49 @@ paint_node_damage_below(struct weston_paint_node *pnode)
}
}
/* Checks if a paint node should be replaced by a solid placeholder
* Checks for 2 types of censor requirements
* - recording_censor: Censor protected view when a
* protected view is captured.
* - unprotected_censor: Censor regions of protected views
* when displayed on an output which has lower protection capability.
* Checks if direct_display is in use.
*/
static void
maybe_replace_paint_node(struct weston_paint_node *pnode)
{
struct weston_output *output = pnode->output;
struct weston_surface *surface = pnode->surface;
struct weston_buffer *buffer = pnode->surface->buffer_ref.buffer;
bool recording_censor =
(output->disable_planes > 0) &&
(surface->desired_protection > WESTON_HDCP_DISABLE);
bool unprotected_censor =
(surface->desired_protection > output->current_protection);
struct weston_solid_buffer_values placeholder_color = {
0.40f, 0.0f, 0.0f, 1.0f
};
pnode->draw_solid = false;
pnode->is_direct = false;
if (buffer->direct_display) {
pnode->draw_solid = true;
pnode->is_direct = true;
pnode->is_opaque = true;
pnode->solid = placeholder_color;
return;
}
if (surface->protection_mode !=
WESTON_SURFACE_PROTECTION_MODE_ENFORCED)
return;
if (recording_censor || unprotected_censor) {
pnode->draw_solid = true;
pnode->is_opaque = true;
pnode->solid = placeholder_color;
}
}
/* Paint nodes contain filter and transform information that needs to be
* up to date before assign_planes() is called. But there are also
* damage related bits that must be updated after assign_planes()
......@@ -220,9 +264,11 @@ paint_node_update_early(struct weston_paint_node *pnode)
static void
paint_node_update_late(struct weston_paint_node *pnode)
{
struct weston_surface *surf = pnode->surface;
bool vis_dirty = pnode->status & PAINT_NODE_VISIBILITY_DIRTY;
bool plane_dirty = pnode->status & PAINT_NODE_PLANE_DIRTY;
bool content_dirty = pnode->status & PAINT_NODE_CONTENT_DIRTY;
bool buffer_dirty = pnode->status & PAINT_NODE_BUFFER_DIRTY;
/* The geoemtry may be shrinking, so we shouldn't just
* add the old visible region to our damage region, because
......@@ -263,9 +309,14 @@ paint_node_update_late(struct weston_paint_node *pnode)
pnode->plane_next = NULL;
}
maybe_replace_paint_node(pnode);
if (buffer_dirty)
surf->compositor->renderer->attach(pnode);
pnode->status &= ~(PAINT_NODE_VISIBILITY_DIRTY |
PAINT_NODE_PLANE_DIRTY |
PAINT_NODE_CONTENT_DIRTY);
PAINT_NODE_CONTENT_DIRTY |
PAINT_NODE_BUFFER_DIRTY);
/* Nothing should be able to flip "early" bits between
* the early and late updates.
......@@ -2979,7 +3030,6 @@ weston_surface_attach_solid(struct weston_surface *surface,
assert(buffer->type == WESTON_BUFFER_SOLID);
weston_buffer_reference(&surface->buffer_ref, buffer,
BUFFER_MAY_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
weston_surface_set_size(surface, w, h);
......@@ -3115,7 +3165,6 @@ weston_surface_attach(struct weston_surface *surface,
weston_buffer_reference(&surface->buffer_ref, NULL,
BUFFER_WILL_NOT_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
surface->width_from_buffer = 0;
surface->height_from_buffer = 0;
......@@ -3155,11 +3204,11 @@ weston_surface_attach(struct weston_surface *surface,
}
status |= WESTON_SURFACE_DIRTY_BUFFER;
weston_surface_dirty_paint_nodes(surface,
PAINT_NODE_BUFFER_DIRTY);
old_buffer = NULL;
weston_buffer_reference(&surface->buffer_ref, buffer,
BUFFER_MAY_BE_ACCESSED);
surface->compositor->renderer->attach(surface, buffer);
return status;
}
......@@ -3194,6 +3243,9 @@ paint_node_add_damage(struct weston_paint_node *node)
assert(!view->transform.dirty);
if (node->draw_solid)
return;
pixman_region32_init(&damage);
if (view->transform.enabled) {
pixman_box32_t *extents;
......@@ -3212,14 +3264,19 @@ paint_node_add_damage(struct weston_paint_node *node)
}
static void
surface_flush_damage(struct weston_surface *surface, struct weston_output *output)
paint_node_flush_surface_damage(struct weston_paint_node *pnode)
{
struct weston_output *output = pnode->output;
struct weston_surface *surface = pnode->surface;
struct weston_buffer *buffer = surface->buffer_ref.buffer;
struct weston_paint_node *node;
struct weston_paint_node *walk_node;
if (buffer->type == WESTON_BUFFER_SHM)
surface->compositor->renderer->flush_damage(surface, buffer,
output);
if (buffer->type == WESTON_BUFFER_SHM) {
if (pnode->draw_solid)
return;
surface->compositor->renderer->flush_damage(pnode);
}
if (!pixman_region32_not_empty(&surface->damage))
return;
......@@ -3227,10 +3284,10 @@ surface_flush_damage(struct weston_surface *surface, struct weston_output *outpu
TL_POINT(surface->compositor, "core_flush_damage",
TLP_SURFACE(surface), TLP_OUTPUT(output), TLP_END);
wl_list_for_each(node, &surface->paint_node_list, surface_link) {
assert(node->surface == surface);
wl_list_for_each(walk_node, &surface->paint_node_list, surface_link) {
assert(walk_node->surface == surface);
paint_node_add_damage(node);
paint_node_add_damage(walk_node);
}
pixman_region32_clear(&surface->damage);
}
......@@ -3284,7 +3341,7 @@ output_accumulate_damage(struct weston_output *output)
continue;
pnode->surface->touched = true;
surface_flush_damage(pnode->surface, output);
paint_node_flush_surface_damage(pnode);
/* Both the renderer and the backend have seen the buffer
* by now. If renderer needs the buffer, it has its own
......@@ -4593,7 +4650,8 @@ weston_surface_commit_state(struct weston_surface *surface,
&surface->surface_to_buffer_matrix);
weston_matrix_invert(&surface->buffer_to_surface_matrix,
&surface->surface_to_buffer_matrix);
weston_surface_dirty_paint_nodes(surface);
weston_surface_dirty_paint_nodes(surface,
PAINT_NODE_VIEW_DIRTY);
weston_surface_update_size(surface);
}
......@@ -6424,6 +6482,7 @@ weston_output_compute_protection(struct weston_output *output)
if (output->current_protection != op_protection) {
output->current_protection = op_protection;
weston_output_dirty_paint_nodes(output);
weston_output_damage(output);
weston_schedule_surface_protection_update(wc);
}
......
......@@ -79,10 +79,8 @@ struct weston_renderer {
const struct weston_size *fb_size,
const struct weston_geometry *area);
void (*flush_damage)(struct weston_surface *surface,
struct weston_buffer *buffer,
struct weston_output *output);
void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
void (*flush_damage)(struct weston_paint_node *pnode);
void (*attach)(struct weston_paint_node *pnode);
void (*destroy)(struct weston_compositor *ec);
/** See weston_surface_copy_content() */
......@@ -509,7 +507,8 @@ enum paint_node_status {
PAINT_NODE_VISIBILITY_DIRTY = 1 << 2,
PAINT_NODE_PLANE_DIRTY = 1 << 3,
PAINT_NODE_CONTENT_DIRTY = 1 << 4,
PAINT_NODE_ALL_DIRTY = (1 << 5) - 1,
PAINT_NODE_BUFFER_DIRTY = 1 << 5,
PAINT_NODE_ALL_DIRTY = (1 << 6) - 1,
};
/**
......@@ -555,6 +554,9 @@ struct weston_paint_node {
uint32_t try_view_on_plane_failure_reasons;
bool is_opaque;
bool is_direct;
bool draw_solid;
struct weston_solid_buffer_values solid;
};
struct weston_paint_node *
......
......@@ -62,15 +62,15 @@ noop_renderer_resize_output(struct weston_output *output,
}
static void
noop_renderer_flush_damage(struct weston_surface *surface,
struct weston_buffer *buffer,
struct weston_output *output)
noop_renderer_flush_damage(struct weston_paint_node *pnode)
{
}
static void
noop_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
noop_renderer_attach(struct weston_paint_node *pnode)
{
struct weston_surface *es = pnode->surface;
struct weston_buffer *buffer = es->buffer_ref.buffer;
struct noop_renderer *renderer =
wl_container_of(es->compositor->renderer, renderer, base);
struct wl_shm_buffer *shm_buffer;
......
......@@ -688,9 +688,7 @@ pixman_renderer_repaint_output(struct weston_output *output,
}
static void
pixman_renderer_flush_damage(struct weston_surface *surface,
struct weston_buffer *buffer,
struct weston_output *output)
pixman_renderer_flush_damage(struct weston_paint_node *pnode)
{
/* No-op for pixman renderer */
}
......@@ -732,7 +730,8 @@ pixman_renderer_surface_set_color(struct weston_surface *es,
}
static void
pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
pixman_renderer_attach_internal(struct weston_surface *es,
struct weston_buffer *buffer)
{
struct pixman_surface_state *ps = get_surface_state(es);
struct wl_shm_buffer *shm_buffer;
......@@ -802,6 +801,15 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
&ps->buffer_destroy_listener);
}
static void
pixman_renderer_attach(struct weston_paint_node *pnode)
{
struct weston_surface *es = pnode->surface;
struct weston_buffer *buffer = pnode->surface->buffer_ref.buffer;
pixman_renderer_attach_internal(es, buffer);
}
static void
pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps)
{
......@@ -899,6 +907,8 @@ pixman_renderer_surface_copy_content(struct weston_surface *surface,
if (!ps->image)
return -1;
pixman_renderer_attach_internal(surface, surface->buffer_ref.buffer);
out_buf = pixman_image_create_bits(format, width, height,
target, width * bytespp);
......
......@@ -1077,10 +1077,11 @@ ensure_surface_buffer_is_ready(struct gl_renderer *gr,
}
static void
censor_override(struct gl_shader_config *sconf,
struct weston_output *output)
prepare_placeholder(struct gl_shader_config *sconf,
struct weston_paint_node *pnode)
{
struct weston_color_transform *ctransf;
struct weston_output *output = pnode->output;
struct gl_renderer *gr = get_renderer(output->compositor);
struct gl_shader_config alt = {
.req = {
......@@ -1089,9 +1090,12 @@ censor_override(struct gl_shader_config *sconf,
},
.projection = sconf->projection,
.view_alpha = sconf->view_alpha,
.unicolor = { 0.40, 0.0, 0.0, 1.0 },
.unicolor = { pnode->solid.r,
pnode->solid.g,
pnode->solid.b,
pnode->solid.a,
},
};
ctransf = output->color_outcome->from_sRGB_to_blend;
if (!gl_shader_config_set_color_transform(gr, &alt, ctransf)) {
weston_log("GL-renderer: %s failed to generate a color transformation.\n",
......@@ -1100,45 +1104,6 @@ censor_override(struct gl_shader_config *sconf,
*sconf = alt;
}
/* Checks if a view needs to be censored on an output
* Checks for 2 types of censor requirements
* - recording_censor: Censor protected view when a
* protected view is captured.
* - unprotected_censor: Censor regions of protected views
* when displayed on an output which has lower protection capability.
* If censoring is needed, smashes the GL shader config.
*/
static void
maybe_censor_override(struct gl_shader_config *sconf,
struct weston_paint_node *pnode)
{
struct weston_output *output = pnode->output;
struct weston_surface *surface = pnode->surface;
struct gl_surface_state *gs = get_surface_state(surface);
struct weston_buffer *buffer = gs->buffer_ref.buffer;
bool recording_censor =
(output->disable_planes > 0) &&
(surface->desired_protection > WESTON_HDCP_DISABLE);
bool unprotected_censor =
(surface->desired_protection > output->current_protection);
if (buffer->direct_display) {
censor_override(sconf, output);
return;
}
/* When not in enforced mode, the client is notified of the protection */
/* change, so content censoring is not required */
if (surface->protection_mode !=
WESTON_SURFACE_PROTECTION_MODE_ENFORCED)
return;
if (recording_censor || unprotected_censor)
censor_override(sconf, output);
}
static void
gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
struct gl_surface_state *gs)
......@@ -1577,7 +1542,7 @@ draw_paint_node(struct weston_paint_node *pnode,
if (!pixman_region32_not_empty(&repaint))
goto out;
if (ensure_surface_buffer_is_ready(gr, gs) < 0)
if (!pnode->draw_solid && ensure_surface_buffer_is_ready(gr, gs) < 0)
goto out;
if (pnode->needs_filtering)
......@@ -1588,17 +1553,14 @@ draw_paint_node(struct weston_paint_node *pnode,
if (!gl_shader_config_init_for_paint_node(&sconf, pnode, filter))
goto out;
/* blended region is whole surface minus opaque region: */
pixman_region32_init_rect(&surface_blend, 0, 0,
pnode->surface->width, pnode->surface->height);
if (pnode->view->geometry.scissor_enabled)
pixman_region32_intersect(&surface_blend, &surface_blend,
&pnode->view->geometry.scissor);
pixman_region32_subtract(&surface_blend, &surface_blend,
&pnode->surface->opaque);
/* XXX: Should we be using ev->transform.opaque here? */
pixman_region32_init(&surface_opaque);
if (pnode->is_opaque)
pixman_region32_init_rect(&surface_opaque, 0, 0,
pnode->surface->width,
pnode->surface->height);
else
pixman_region32_init(&surface_opaque);
if (pnode->view->geometry.scissor_enabled)
pixman_region32_intersect(&surface_opaque,
&pnode->surface->opaque,
......@@ -1606,7 +1568,17 @@ draw_paint_node(struct weston_paint_node *pnode,
else
pixman_region32_copy(&surface_opaque, &pnode->surface->opaque);
maybe_censor_override(&sconf, pnode);
/* blended region is whole surface minus opaque region: */
pixman_region32_init_rect(&surface_blend, 0, 0,
pnode->surface->width, pnode->surface->height);
if (pnode->view->geometry.scissor_enabled)
pixman_region32_intersect(&surface_blend, &surface_blend,
&pnode->view->geometry.scissor);
pixman_region32_subtract(&surface_blend, &surface_blend,
&surface_opaque);
if (pnode->draw_solid)
prepare_placeholder(&sconf, pnode);
if (pixman_region32_not_empty(&surface_opaque)) {
struct gl_shader_config alt = sconf;
......@@ -1679,7 +1651,6 @@ update_buffer_release_fences(struct weston_compositor *compositor,
wl_list_for_each_reverse(pnode, &output->paint_node_z_order_list,
z_order_link) {
struct weston_view *view = pnode->view;
struct gl_surface_state *gs;
struct weston_buffer_release *buffer_release;
int fence_fd;
......@@ -1687,7 +1658,10 @@ update_buffer_release_fences(struct weston_compositor *compositor,
if (pnode->plane != &output->primary_plane)
continue;
gs = get_surface_state(view->surface);
if (pnode->draw_solid)
continue;
gs = get_surface_state(pnode->surface);
buffer_release = gs->buffer_release_ref.buffer_release;
if (!gs->used_in_output_repaint || !buffer_release)
......@@ -2183,7 +2157,7 @@ gl_renderer_repaint_output(struct weston_output *output,
z_order_link) {
if (pnode->plane == &output->primary_plane) {
struct gl_surface_state *gs =
get_surface_state(pnode->view->surface);
get_surface_state(pnode->surface);
gs->used_in_output_repaint = false;
}
}
......@@ -2394,16 +2368,14 @@ gl_format_from_internal(GLenum internal_format)
}
static void
gl_renderer_flush_damage(struct weston_surface *surface,
struct weston_buffer *buffer,
struct weston_output *output)
gl_renderer_flush_damage_internal(struct weston_surface *surface,
bool just_accumulate)
{
const struct weston_testsuite_quirks *quirks =
&surface->compositor->test_data.test_quirks;
struct weston_buffer *buffer = surface->buffer_ref.buffer;
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = gs->buffer;
struct weston_paint_node *pnode;
bool texture_used;
pixman_box32_t *rectangles;
uint8_t *data;
int i, j, n;
......@@ -2413,31 +2385,15 @@ gl_renderer_flush_damage(struct weston_surface *surface,
pixman_region32_union(&gb->texture_damage,
&gb->texture_damage, &surface->damage);
if (just_accumulate)
return;
/* This can happen if a SHM wl_buffer gets destroyed before we flush
* damage, because wayland-server just nukes the wl_shm_buffer from
* underneath us */
if (!buffer->shm_buffer)
return;
/* Avoid upload, if the texture won't be used this time.
* We still accumulate the damage in texture_damage, and
* hold the reference to the buffer, in case the surface
* migrates back to the primary plane.
*
* When called from gl_renderer_surface_copy_content()
* or gl_renderer_create_surface(), output is NULL.
* In that case, always upload.
*/
texture_used = false;
wl_list_for_each(pnode, &surface->paint_node_list, surface_link) {
if (!output || pnode->plane == &output->primary_plane) {
texture_used = true;
break;
}
}
if (!texture_used)
return;
if (!pixman_region32_not_empty(&gb->texture_damage) &&
!gb->needs_full_upload)
goto done;
......@@ -2509,6 +2465,23 @@ done:
weston_buffer_release_reference(&gs->buffer_release_ref, NULL);
}
static void
gl_renderer_flush_damage(struct weston_paint_node *pnode)
{
bool just_accumulate = false;
/* Avoid upload, if the texture won't be used this time.
* We still accumulate the damage in texture_damage, and
* hold the reference to the buffer, in case the surface
* migrates back to the primary plane.
*/
if (pnode->plane != &pnode->output->primary_plane)
just_accumulate = true;
gl_renderer_flush_damage_internal(pnode->surface,
just_accumulate);
}
static void
destroy_buffer_state(struct gl_buffer_state *gb)
{
......@@ -2557,7 +2530,7 @@ ensure_textures(struct gl_buffer_state *gb, GLenum target, int num_textures)
glBindTexture(target, 0);
}
static bool
static void
gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
{
struct weston_compositor *ec = es->compositor;
......@@ -2685,16 +2658,14 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
buffer->pixel_format == old_buffer->pixel_format) {
gs->buffer->pitch = pitch;
memcpy(gs->buffer->offset, offset, sizeof(offset));
return true;
return;
}
if (gs->buffer)
destroy_buffer_state(gs->buffer);
gs->buffer = NULL;
gb = zalloc(sizeof(*gb));
if (!gb)
return false;
gb = xzalloc(sizeof(*gb));
gb->gr = gr;
wl_list_init(&gb->destroy_listener.link);
......@@ -2711,8 +2682,6 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
gs->surface = es;
ensure_textures(gb, GL_TEXTURE_2D, num_planes);
return true;
}
static bool
......@@ -2833,7 +2802,7 @@ err_free:
return false;
}
static bool
static void
gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
{
struct weston_compositor *ec = es->compositor;
......@@ -2853,8 +2822,6 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
glBindTexture(target, gb->textures[i]);
gr->image_target_texture_2d(target, gb->images[i]);
}
return true;
}
static void
......@@ -3343,18 +3310,19 @@ ensure_renderer_gl_buffer_state(struct weston_surface *surface,
}
static void
attach_direct_display_censor_placeholder(struct weston_surface *surface,
struct weston_buffer *buffer)
attach_direct_display_placeholder(struct weston_paint_node *pnode)
{
struct weston_surface *surface = pnode->surface;
struct weston_buffer *buffer = surface->buffer_ref.buffer;
struct gl_buffer_state *gb;
gb = ensure_renderer_gl_buffer_state(surface, buffer);
/* uses the same color as the content-protection placeholder */
gb->color[0] = 0.40f;
gb->color[1] = 0.0f;
gb->color[2] = 0.0f;
gb->color[3] = 1.0f;
gb->color[0] = pnode->solid.r;
gb->color[1] = pnode->solid.g;
gb->color[2] = pnode->solid.b;
gb->color[3] = pnode->solid.a;
gb->shader_variant = SHADER_VARIANT_SOLID;
}
......@@ -3371,11 +3339,6 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
GLenum target;
int i;
if (buffer->direct_display) {
attach_direct_display_censor_placeholder(surface, buffer);
return true;
}
/* Thanks to linux-dmabuf being totally independent of libweston,
* the first time a dmabuf is attached, the gl_buffer_state will
* only be set as userdata on the dmabuf, not on the weston_buffer.
......@@ -3473,7 +3436,7 @@ out:
return ret;
}
static bool
static void
gl_renderer_attach_solid(struct weston_surface *surface,
struct weston_buffer *buffer)
{
......@@ -3487,18 +3450,15 @@ gl_renderer_attach_solid(struct weston_surface *surface,
gb->color[3] = buffer->solid.a;
gb->shader_variant = SHADER_VARIANT_SOLID;
return true;
}
static void
gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
gl_renderer_attach_internal(struct weston_surface *es,
struct weston_buffer *buffer,
struct weston_paint_node *direct_pnode)
{
struct gl_surface_state *gs = get_surface_state(es);
bool ret = false;
/* If get_surface_state called gl_renderer_create_surface, it did
* attach the buffer */
if (gs->buffer_ref.buffer == buffer)
return;
......@@ -3521,30 +3481,32 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
if (!buffer)
goto out;
if (direct_pnode) {
attach_direct_display_placeholder(direct_pnode);
goto success;
}
switch (buffer->type) {
case WESTON_BUFFER_SHM:
ret = gl_renderer_attach_shm(es, buffer);
gl_renderer_attach_shm(es, buffer);
break;
case WESTON_BUFFER_DMABUF:
ret = gl_renderer_attach_dmabuf(es, buffer);
gl_renderer_attach_dmabuf(es, buffer);
break;
case WESTON_BUFFER_RENDERER_OPAQUE:
ret = gl_renderer_attach_egl(es, buffer);
gl_renderer_attach_egl(es, buffer);
break;
case WESTON_BUFFER_SOLID:
ret = gl_renderer_attach_solid(es, buffer);
gl_renderer_attach_solid(es, buffer);
break;
default:
break;
}
if (!ret) {
weston_log("unhandled buffer type!\n");
weston_buffer_send_server_error(buffer,
"disconnecting due to unhandled buffer type");
goto out;
}
success:
weston_buffer_reference(&gs->buffer_ref, buffer,
BUFFER_MAY_BE_ACCESSED);
weston_buffer_release_reference(&gs->buffer_release_ref,
......@@ -3558,6 +3520,18 @@ out:
weston_buffer_release_reference(&gs->buffer_release_ref, NULL);
}
static void
gl_renderer_attach(struct weston_paint_node *pnode)
{
struct weston_surface *es = pnode->surface;
struct weston_buffer *buffer = es->buffer_ref.buffer;
if (pnode->is_direct)
gl_renderer_attach_internal(es, buffer, pnode);
else
gl_renderer_attach_internal(es, buffer, NULL);
}
static uint32_t
pack_color(pixman_format_code_t format, float *c)
{
......@@ -3607,16 +3581,22 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
const GLenum gl_format = GL_RGBA; /* PIXMAN_a8b8g8r8 little-endian */
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_buffer_state *gb = gs->buffer;
struct weston_buffer *buffer = gs->buffer_ref.buffer;
struct gl_surface_state *gs;
struct gl_buffer_state *gb;
struct weston_buffer *buffer;
int cw, ch;
GLuint fbo;
GLuint tex;
GLenum status;
int ret = -1;
gl_renderer_attach_internal(surface, surface->buffer_ref.buffer, NULL);
gs = get_surface_state(surface);
gb = gs->buffer;
buffer = gs->buffer_ref.buffer;
assert(buffer);
if (buffer->direct_display)
return -1;
cw = buffer->width;
ch = buffer->height;
......@@ -3626,7 +3606,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
*(uint32_t *)target = pack_color(format, gb->color);
return 0;
case WESTON_BUFFER_SHM:
gl_renderer_flush_damage(surface, buffer, NULL);
gl_renderer_flush_damage_internal(surface, false);
/* fall through */
case WESTON_BUFFER_DMABUF:
case WESTON_BUFFER_RENDERER_OPAQUE:
......@@ -3764,15 +3744,6 @@ gl_renderer_create_surface(struct weston_surface *surface)
wl_signal_add(&gr->destroy_signal,
&gs->renderer_destroy_listener);
if (surface->buffer_ref.buffer) {
gl_renderer_attach(surface, surface->buffer_ref.buffer);
if (surface->buffer_ref.buffer->type == WESTON_BUFFER_SHM) {
gl_renderer_flush_damage(surface,
surface->buffer_ref.buffer,
NULL);
}
}
return 0;
}
......