Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 31 additions & 37 deletions src/stream-chooser/outputwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,24 @@ static void frame_handle_presentation_time(void*,
{}

static void frame_handle_ready(void *data,
struct ext_image_copy_capture_frame_v1*)
struct ext_image_copy_capture_frame_v1 *frame)
{
WayfireChooserOutput *output = (WayfireChooserOutput*)data;

output->buffer_ready();
output->frame_in_flight = false;

ext_image_copy_capture_frame_v1_destroy(frame);
output->frame = nullptr;
}

static void frame_handle_failed(void *data,
struct ext_image_copy_capture_frame_v1 *handle,
struct ext_image_copy_capture_frame_v1 *frame,
uint32_t reason)
{
WayfireChooserOutput *output = (WayfireChooserOutput*)data;
std::cerr << "Failed to copy frame because reason: " << reason << std::endl;
ext_image_copy_capture_frame_v1_destroy(handle);

ext_image_copy_capture_frame_v1_destroy(frame);
output->frame = nullptr;
output->frame_in_flight = false;
}

static const struct ext_image_copy_capture_frame_v1_listener frame_listener = {
Expand Down Expand Up @@ -94,36 +96,31 @@ static const struct ext_image_copy_capture_session_v1_listener recording_session
.stopped = session_handle_stopped,
};

static void dmabuf_created(void *data, struct zwp_linux_buffer_params_v1*,
struct wl_buffer *wl_buffer)
{
auto output = (WayfireChooserOutput*)data;
output->buffer->buffer = wl_buffer;
}

static void dmabuf_failed(void*, struct zwp_linux_buffer_params_v1*)
{
std::cerr << "Failed to create dmabuf" << std::endl;
}

static const struct zwp_linux_buffer_params_v1_listener params_listener = {
.created = dmabuf_created,
.failed = dmabuf_failed,
};

static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireChooserOutput *output)
{
auto format = (output->current_buffer_format == WL_SHM_FORMAT_XRGB8888) ?
GBM_FORMAT_XRGB8888 : GBM_FORMAT_ARGB8888;

auto buffer = output->buffer;

if (buffer->gbm_fd > 0)
{
close(buffer->gbm_fd);
buffer->gbm_fd = -1;
}

if (buffer->bo)
{
gbm_bo_destroy(buffer->bo);
buffer->bo = nullptr;
}

if (buffer->buffer)
{
wl_buffer_destroy(buffer->buffer);
buffer->buffer = nullptr;
}

if (buffer->params)
{
zwp_linux_buffer_params_v1_destroy(buffer->params);
Expand Down Expand Up @@ -154,14 +151,14 @@ static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireCh
buffer->params = zwp_linux_dmabuf_v1_create_params(WayfireStreamChooserApp::getInstance().dmabuf);

uint64_t mod = gbm_bo_get_modifier(buffer->bo);
buffer->gbm_fd = gbm_bo_get_fd(buffer->bo);
zwp_linux_buffer_params_v1_add(buffer->params,
gbm_bo_get_fd(buffer->bo), 0,
buffer->gbm_fd, 0,
gbm_bo_get_offset(buffer->bo, 0),
gbm_bo_get_stride(buffer->bo),
mod >> 32, mod & 0xffffffff);

zwp_linux_buffer_params_v1_add_listener(buffer->params, &params_listener, output);
zwp_linux_buffer_params_v1_create(buffer->params, w, h, format, 0);
buffer->buffer = zwp_linux_buffer_params_v1_create_immed(buffer->params, w, h, format, 0);
}

void WayfireChooserOutput::start_output_source_ssession()
Expand Down Expand Up @@ -294,16 +291,21 @@ WayfireChooserOutput::~WayfireChooserOutput()
ext_image_copy_capture_session_v1_destroy(recording_session);
}

if (buffer->buffer)
if (buffer->gbm_fd > 0)
{
wl_buffer_destroy(buffer->buffer);
close(buffer->gbm_fd);
}

if (buffer->bo)
{
gbm_bo_destroy(buffer->bo);
}

if (buffer->buffer)
{
wl_buffer_destroy(buffer->buffer);
}

if (buffer->params)
{
zwp_linux_buffer_params_v1_destroy(buffer->params);
Expand Down Expand Up @@ -355,11 +357,6 @@ void WayfireChooserOutput::frame_request()
return;
}

if (frame_in_flight)
{
return;
}

if (frame)
{
ext_image_copy_capture_frame_v1_destroy(frame);
Expand All @@ -373,7 +370,6 @@ void WayfireChooserOutput::frame_request()
ext_image_copy_capture_frame_v1_attach_buffer(buffer->frame, buffer->buffer);
ext_image_copy_capture_frame_v1_damage_buffer(buffer->frame, 0, 0, buffer->width, buffer->height);
ext_image_copy_capture_frame_v1_capture(buffer->frame);
frame_in_flight = true;
}

void WayfireChooserOutput::buffer_ready()
Expand All @@ -399,10 +395,10 @@ void WayfireChooserOutput::buffer_ready()
std::shared_ptr<Glib::Bytes> bytes = 0;
size_t size = stride * buffer->height;
bytes = Glib::Bytes::create((unsigned char*)data, size);
gbm_bo_unmap(buffer->bo, map_data);

if (!bytes)
{
gbm_bo_unmap(buffer->bo, map_data);
return;
}

Expand All @@ -416,6 +412,4 @@ void WayfireChooserOutput::buffer_ready()
auto texture = builder->build();

contents.set_paintable(texture);

gbm_bo_unmap(buffer->bo, map_data);
}
2 changes: 1 addition & 1 deletion src/stream-chooser/outputwidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct output_buffer
int height = 0;
int stride = 0;
gbm_bo *bo = nullptr;
int gbm_fd = -1;
wl_buffer *buffer = nullptr;
zwp_linux_buffer_params_v1 *params = nullptr;
ext_image_copy_capture_frame_v1 *frame = NULL;
Expand All @@ -38,7 +39,6 @@ class WayfireChooserOutput : public Gtk::Box
ext_image_copy_capture_session_v1 *recording_session = NULL;
std::shared_ptr<output_buffer> buffer = nullptr;
ext_image_copy_capture_frame_v1 *frame = NULL;
bool frame_in_flight = false;
void print();
void frame_request();
void buffer_ready();
Expand Down
45 changes: 27 additions & 18 deletions src/stream-chooser/stream-chooser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,19 @@ static void registry_add_object(void *data, wl_registry *registry, uint32_t name
wl_registry_bind(registry, name,
&ext_foreign_toplevel_list_v1_interface,
version);
WayfireStreamChooserApp::getInstance().has_foreign_toplevel_list = true;
WayfireStreamChooserApp::getInstance().set_toplevel_list(list);
ext_foreign_toplevel_list_v1_add_listener(list,
&toplevel_list_v1_impl, NULL);
} else if (strcmp(interface, ext_image_copy_capture_manager_v1_interface.name) == 0)
{
auto manager = (ext_image_copy_capture_manager_v1*)wl_registry_bind(registry, name,
&ext_image_copy_capture_manager_v1_interface, version);
WayfireStreamChooserApp::getInstance().has_image_copy_capture = true;
WayfireStreamChooserApp::getInstance().set_copy_capture_manager(manager);
} else if (strcmp(interface, ext_foreign_toplevel_image_capture_source_manager_v1_interface.name) == 0)
{
auto toplevel_capture_manager =
(ext_foreign_toplevel_image_capture_source_manager_v1*)wl_registry_bind(registry, name,
&ext_foreign_toplevel_image_capture_source_manager_v1_interface, version);
WayfireStreamChooserApp::getInstance().has_image_capture_source = true;
WayfireStreamChooserApp::getInstance().set_toplevel_capture_manager(toplevel_capture_manager);
} else if (strcmp(interface, ext_output_image_capture_source_manager_v1_interface.name) == 0)
{
Expand Down Expand Up @@ -281,24 +278,45 @@ void WayfireStreamChooserApp::activate()
wl_display_roundtrip(display);
wl_registry_destroy(registry);

if (!has_image_copy_capture)
bool toplevel_capture = true;
bool output_capture = true;
if (!this->manager)
{
std::cerr << "Compositor has not advertised ext-image-copy-capture-v1" << std::endl;
toplevel_capture = false;
}

if (!has_foreign_toplevel_list)
if (!this->list)
{
std::cerr << "Compositor has not advertised ext-foreign-toplevel-list-v1" << std::endl;
toplevel_capture = false;
}

if (!has_image_capture_source)
if (!this->output_capture_manager)
{
std::cerr << "Compositor has not advertised ext-image-capture-source-v1" << std::endl;
output_capture = false;
}

window_label.set_sensitive(false);
window_label.set_tooltip_text("This compositor does not currently support sharing individual windows");
notebook.set_current_page(1);
if (!this->toplevel_capture_manager)
{
std::cerr << "Compositor has not advertised ext-foreign-toplevel-image-capture-source-v1" <<
std::endl;
toplevel_capture = false;
}

if (!toplevel_capture)
{
if (!output_capture)
{
std::cerr << "No capture protocols supported, nothing to do." << std::endl;
exit(EXIT_FAILURE);
}

window_label.set_sensitive(false);
window_label.set_tooltip_text("This compositor does not currently support sharing individual windows");
notebook.set_current_page(1);
}

/* Get output list */
auto gtkdisplay = Gdk::Display::get_default();
Expand Down Expand Up @@ -357,7 +375,6 @@ void WayfireStreamChooserApp::activate()
window.present();
}

static bool first_toplevel = true;
void WayfireStreamChooserApp::add_toplevel(ext_foreign_toplevel_handle_v1 *handle)
{
toplevels.emplace(handle, new WayfireChooserTopLevel(handle));
Expand All @@ -367,14 +384,6 @@ void WayfireStreamChooserApp::add_toplevel(ext_foreign_toplevel_handle_v1 *handl
auto child = window_list.get_child_at_index(0);
window_list.select_child(*child);
}

window_label.set_sensitive(true);
window_label.set_tooltip_text("");
if (first_toplevel)
{
first_toplevel = false;
notebook.set_current_page(0);
}
}

void WayfireStreamChooserApp::remove_toplevel(WayfireChooserTopLevel *toplevel)
Expand Down
3 changes: 0 additions & 3 deletions src/stream-chooser/stream-chooser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ class WayfireStreamChooserApp : public Gtk::Application
public:
Gtk::Notebook notebook;
Gtk::FlowBox window_list, screen_list;
bool has_foreign_toplevel_list = false;
bool has_image_copy_capture = false;
bool has_image_capture_source = false;
std::string drm_device_name;
int drm_fd = -1;
gbm_device *gbm_device_ptr = nullptr;
Expand Down
Loading
Loading