}
static void
-drm_fb_set_buffer(struct drm_fb *fb, struct wl_buffer *buffer)
+drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
{
assert(fb->buffer_ref.buffer == NULL);
struct drm_output *output = (struct drm_output *) _output;
struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
- struct wl_buffer *buffer = es->buffer_ref.buffer;
+ struct weston_buffer *buffer = es->buffer_ref.buffer;
struct gbm_bo *bo;
uint32_t format;
if (es->alpha != 1.0f)
return NULL;
- if (wl_buffer_is_shm(es->buffer_ref.buffer))
+ if (wl_shm_buffer_get(es->buffer_ref.buffer->resource))
return NULL;
if (!drm_surface_transform_supported(es))
if (c->cursors_are_broken)
return NULL;
if (es->buffer_ref.buffer == NULL ||
- !wl_buffer_is_shm(es->buffer_ref.buffer) ||
+ !wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
es->geometry.width > 64 || es->geometry.height > 64)
return NULL;
output->current_cursor ^= 1;
bo = output->cursor_bo[output->current_cursor];
memset(buf, 0, sizeof buf);
- stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer);
- s = wl_shm_buffer_get_data(es->buffer_ref.buffer);
+ stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer);
+ s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer);
for (i = 0; i < es->geometry.height; i++)
memcpy(buf + i * 64, s + i * stride,
es->geometry.width * 4);
* non-shm, or small enough to be a cursor
*/
if ((es->buffer_ref.buffer &&
- !wl_buffer_is_shm(es->buffer_ref.buffer)) ||
+ !wl_shm_buffer_get(es->buffer_ref.buffer->resource)) ||
(es->geometry.width <= 64 && es->geometry.height <= 64))
es->keep_buffer = 1;
else
}
static void
+weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
+{
+ struct weston_buffer *buffer =
+ container_of(listener, struct weston_buffer, destroy_listener);
+
+ wl_signal_emit(&buffer->destroy_signal, buffer);
+ free(buffer);
+}
+
+struct weston_buffer *
+weston_buffer_from_resource(struct wl_resource *resource)
+{
+ struct weston_buffer *buffer;
+ struct wl_listener *listener;
+
+ listener = wl_resource_get_destroy_listener(resource,
+ weston_buffer_destroy_handler);
+
+ if (listener) {
+ buffer = container_of(listener, struct weston_buffer,
+ destroy_listener);
+ } else {
+ buffer = malloc(sizeof *buffer);
+ memset(buffer, 0, sizeof *buffer);
+
+ buffer->resource = resource;
+ wl_signal_init(&buffer->destroy_signal);
+ buffer->destroy_listener.notify = weston_buffer_destroy_handler;
+ wl_resource_add_destroy_listener(resource,
+ &buffer->destroy_listener);
+ }
+
+ return buffer;
+}
+
+static void
weston_buffer_reference_handle_destroy(struct wl_listener *listener,
void *data)
{
container_of(listener, struct weston_buffer_reference,
destroy_listener);
- assert((struct wl_buffer *)data == ref->buffer);
+ assert((struct weston_buffer *)data == ref->buffer);
ref->buffer = NULL;
}
WL_EXPORT void
weston_buffer_reference(struct weston_buffer_reference *ref,
- struct wl_buffer *buffer)
+ struct weston_buffer *buffer)
{
if (ref->buffer && buffer != ref->buffer) {
ref->buffer->busy_count--;
if (ref->buffer->busy_count == 0) {
- assert(ref->buffer->resource.client != NULL);
- wl_resource_queue_event(&ref->buffer->resource,
+ assert(wl_resource_get_client(ref->buffer->resource));
+ wl_resource_queue_event(ref->buffer->resource,
WL_BUFFER_RELEASE);
}
wl_list_remove(&ref->destroy_listener.link);
if (buffer && buffer != ref->buffer) {
buffer->busy_count++;
- wl_signal_add(&buffer->resource.destroy_signal,
+ wl_signal_add(&buffer->destroy_signal,
&ref->destroy_listener);
}
}
static void
-weston_surface_attach(struct weston_surface *surface, struct wl_buffer *buffer)
+weston_surface_attach(struct weston_surface *surface,
+ struct weston_buffer *buffer)
{
weston_buffer_reference(&surface->buffer_ref, buffer);
pixman_region32_t *opaque)
{
if (surface->buffer_ref.buffer &&
- wl_buffer_is_shm(surface->buffer_ref.buffer))
+ wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
surface->compositor->renderer->flush_damage(surface);
if (surface->transform.enabled) {
struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
{
struct weston_surface *surface = wl_resource_get_user_data(resource);
- struct wl_buffer *buffer = NULL;
+ struct weston_buffer *buffer = NULL;
if (buffer_resource)
- buffer = buffer_resource->data;
+ buffer = weston_buffer_from_resource(buffer_resource);
/* Attach, attach, without commit in between does not send
* wl_buffer.release. */
surface->pending.buffer = buffer;
surface->pending.newly_attached = 1;
if (buffer) {
- wl_signal_add(&buffer->resource.destroy_signal,
+ wl_signal_add(&buffer->destroy_signal,
&surface->pending.buffer_destroy_listener);
}
}
};
struct weston_surface;
+struct weston_buffer;
struct shell_surface;
struct weston_seat;
struct weston_output;
void (*repaint_output)(struct weston_output *output,
pixman_region32_t *output_damage);
void (*flush_damage)(struct weston_surface *surface);
- void (*attach)(struct weston_surface *es, struct wl_buffer *buffer);
+ void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
int (*create_surface)(struct weston_surface *surface);
void (*surface_set_color)(struct weston_surface *surface,
float red, float green,
struct weston_xkb_info xkb_info;
};
+struct weston_buffer {
+ struct wl_resource *resource;
+ struct wl_signal destroy_signal;
+ struct wl_listener destroy_listener;
+
+ union {
+ struct wl_shm_buffer *shm_buffer;
+ struct wl_buffer *legacy_buffer;
+ };
+ int32_t width, height;
+ uint32_t busy_count;
+};
+
struct weston_buffer_reference {
- struct wl_buffer *buffer;
+ struct weston_buffer *buffer;
struct wl_listener destroy_listener;
};
struct {
/* wl_surface.attach */
int newly_attached;
- struct wl_buffer *buffer;
+ struct weston_buffer *buffer;
struct wl_listener buffer_destroy_listener;
int32_t sx;
int32_t sy;
struct weston_surface *
weston_surface_get_main_surface(struct weston_surface *surface);
+struct weston_buffer *
+weston_buffer_from_resource(struct wl_resource *resource);
+
void
weston_buffer_reference(struct weston_buffer_reference *ref,
- struct wl_buffer *buffer);
+ struct weston_buffer *buffer);
uint32_t
weston_compositor_get_time(void);
{
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
- struct wl_buffer *buffer = gs->buffer_ref.buffer;
+ struct weston_buffer *buffer = gs->buffer_ref.buffer;
#ifdef GL_UNPACK_ROW_LENGTH
pixman_box32_t *rectangles;
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
gs->pitch, buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE,
- wl_shm_buffer_get_data(buffer));
+ wl_shm_buffer_get_data(buffer->shm_buffer));
goto done;
}
#ifdef GL_UNPACK_ROW_LENGTH
/* Mesa does not define GL_EXT_unpack_subimage */
glPixelStorei(GL_UNPACK_ROW_LENGTH, gs->pitch);
- data = wl_shm_buffer_get_data(buffer);
+ data = wl_shm_buffer_get_data(buffer->shm_buffer);
rectangles = pixman_region32_rectangles(&gs->texture_damage, &n);
for (i = 0; i < n; i++) {
pixman_box32_t r;
}
static void
-gl_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
+gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
+ struct wl_shm_buffer *shm_buffer;
EGLint attribs[3], format;
int i, num_planes;
return;
}
- if (wl_buffer_is_shm(buffer)) {
+ shm_buffer = wl_shm_buffer_get(buffer->resource);
+ if (shm_buffer) {
+ buffer->shm_buffer = shm_buffer;
+ buffer->width = wl_shm_buffer_get_width(shm_buffer);
+ buffer->height = wl_shm_buffer_get_height(shm_buffer);
+
/* Only allocate a texture if it doesn't match existing one.
* If gs->num_images is not 0, then a switch from DRM allocated
* buffer to a SHM buffer is happening, and we need to allocate
* a new texture buffer. */
- if (wl_shm_buffer_get_stride(buffer) / 4 != gs->pitch ||
- wl_shm_buffer_get_height(buffer) != gs->height ||
+ if (wl_shm_buffer_get_stride(shm_buffer) / 4 != gs->pitch ||
+ buffer->height != gs->height ||
gs->num_images > 0) {
- gs->pitch = wl_shm_buffer_get_stride(buffer) / 4;
- gs->height = wl_shm_buffer_get_height(buffer);
+ gs->pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
+ gs->height = buffer->height;
gs->target = GL_TEXTURE_2D;
ensure_textures(gs, 1);
gs->height / es->buffer_scale);
}
- if (wl_shm_buffer_get_format(buffer) == WL_SHM_FORMAT_XRGB8888)
+ if (wl_shm_buffer_get_format(shm_buffer) == WL_SHM_FORMAT_XRGB8888)
gs->shader = &gr->texture_shader_rgbx;
else
gs->shader = &gr->texture_shader_rgba;
- } else if (gr->query_buffer(gr->egl_display, buffer,
+ } else if (gr->query_buffer(gr->egl_display,
+ (struct wl_buffer *)buffer->resource,
EGL_TEXTURE_FORMAT, &format)) {
+ buffer->legacy_buffer = (struct wl_buffer *)buffer->resource;
+ buffer->width = buffer->legacy_buffer->width;
+ buffer->height = buffer->legacy_buffer->height;
+
for (i = 0; i < gs->num_images; i++)
gr->destroy_image(gr->egl_display, gs->images[i]);
gs->num_images = 0;
gs->images[i] = gr->create_image(gr->egl_display,
NULL,
EGL_WAYLAND_BUFFER_WL,
- buffer, attribs);
+ buffer->legacy_buffer,
+ attribs);
if (!gs->images[i]) {
weston_log("failed to create img for plane %d\n", i);
continue;
}
static void
-noop_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
+noop_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
}
}
static void
-pixman_renderer_attach(struct weston_surface *es, struct wl_buffer *buffer)
+pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
struct pixman_surface_state *ps = get_surface_state(es);
+ struct wl_shm_buffer *shm_buffer;
pixman_format_code_t pixman_format;
weston_buffer_reference(&ps->buffer_ref, buffer);
if (!buffer)
return;
+
+ shm_buffer = wl_shm_buffer_get(buffer->resource);
- if (!wl_buffer_is_shm(buffer)) {
+ if (! shm_buffer) {
weston_log("Pixman renderer supports only SHM buffers\n");
weston_buffer_reference(&ps->buffer_ref, NULL);
return;
}
- switch (wl_shm_buffer_get_format(buffer)) {
+ switch (wl_shm_buffer_get_format(shm_buffer)) {
case WL_SHM_FORMAT_XRGB8888:
pixman_format = PIXMAN_x8r8g8b8;
break;
return;
break;
}
+
+ buffer->shm_buffer = shm_buffer;
+ buffer->width = wl_shm_buffer_get_width(shm_buffer);
+ buffer->height = wl_shm_buffer_get_height(shm_buffer);
+
ps->image = pixman_image_create_bits(pixman_format,
- wl_shm_buffer_get_width(buffer),
- wl_shm_buffer_get_height(buffer),
- wl_shm_buffer_get_data(buffer),
- wl_shm_buffer_get_stride(buffer));
+ buffer->width, buffer->height,
+ wl_shm_buffer_get_data(shm_buffer),
+ wl_shm_buffer_get_stride(shm_buffer));
}
static int
#define PREMULT_ALPHA_FLAG (1 << 31)
static VC_IMAGE_TYPE_T
-shm_buffer_get_vc_format(struct wl_buffer *buffer)
+shm_buffer_get_vc_format(struct wl_shm_buffer *buffer)
{
switch (wl_shm_buffer_get_format(buffer)) {
case WL_SHM_FORMAT_XRGB8888:
}
static int
-rpi_resource_update(struct rpi_resource *resource, struct wl_buffer *buffer,
+rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
pixman_region32_t *region)
{
pixman_region32_t write_region;
if (!buffer)
return -1;
- ifmt = shm_buffer_get_vc_format(buffer);
- width = wl_shm_buffer_get_width(buffer);
- height = wl_shm_buffer_get_height(buffer);
- stride = wl_shm_buffer_get_stride(buffer);
- pixels = wl_shm_buffer_get_data(buffer);
+ ifmt = shm_buffer_get_vc_format(buffer->shm_buffer);
+ width = wl_shm_buffer_get_width(buffer->shm_buffer);
+ height = wl_shm_buffer_get_height(buffer->shm_buffer);
+ stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
+ pixels = wl_shm_buffer_get_data(buffer->shm_buffer);
ret = rpi_resource_realloc(resource, ifmt & ~PREMULT_ALPHA_FLAG,
width, height, stride, height);
}
static int
-rpir_surface_damage(struct rpir_surface *surface, struct wl_buffer *buffer,
+rpir_surface_damage(struct rpir_surface *surface, struct weston_buffer *buffer,
pixman_region32_t *damage)
{
pixman_region32_t upload;
* having an shm buffer.
*/
struct rpir_surface *surface = to_rpir_surface(base);
- struct wl_buffer *buffer = surface->buffer_ref.buffer;
+ struct weston_buffer *buffer = surface->buffer_ref.buffer;
int ret;
assert(buffer);
- assert(wl_buffer_is_shm(buffer));
+ assert(wl_shm_buffer_get(buffer->resource));
ret = rpir_surface_damage(surface, buffer, &base->damage);
if (ret)
}
static void
-rpi_renderer_attach(struct weston_surface *base, struct wl_buffer *buffer)
+rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
{
/* Called every time a client commits an attach. */
static int warned;
if (!surface)
return;
- if (buffer && !wl_buffer_is_shm(buffer) && !warned) {
+ if (buffer && !wl_shm_buffer_get(buffer->resource) && !warned) {
weston_log("Error: non-wl_shm buffers not supported.\n");
warned = 1;
return;
}
+ if (wl_shm_buffer_get(buffer->resource)) {
+ buffer->shm_buffer = wl_shm_buffer_get(buffer->resource);
+ buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer);
+ buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
+ }
+
weston_buffer_reference(&surface->buffer_ref, buffer);
/* XXX: need to check if in middle of update
struct screenshooter_frame_listener {
struct wl_listener listener;
- struct wl_buffer *buffer;
+ struct weston_buffer *buffer;
struct wl_resource *resource;
};
0, 0, output->current->width,
output->current->height);
- stride = wl_shm_buffer_get_stride(l->buffer);
+ stride = wl_shm_buffer_get_stride(l->buffer->shm_buffer);
- d = wl_shm_buffer_get_data(l->buffer);
+ d = wl_shm_buffer_get_data(l->buffer->shm_buffer);
s = pixels + stride * (l->buffer->height - 1);
switch (compositor->read_format) {
struct weston_output *output =
wl_resource_get_user_data(output_resource);
struct screenshooter_frame_listener *l;
- struct wl_buffer *buffer = buffer_resource->data;
+ struct weston_buffer *buffer =
+ weston_buffer_from_resource(buffer_resource);
- if (!wl_buffer_is_shm(buffer))
+ if (!wl_shm_buffer_get(buffer->resource))
return;
+
+ buffer->shm_buffer = wl_shm_buffer_get(buffer->resource);
+ buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer);
+ buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
if (buffer->width < output->current->width ||
buffer->height < output->current->height)