Property::Property(Card& card, uint32_t id) : DrmObject(card, id, DRM_MODE_OBJECT_PROPERTY) { m_priv = new PropertyPriv(); m_priv->drm_prop = drmModeGetProperty(card.fd(), id); m_name = m_priv->drm_prop->name; }
ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, uint8_t depth, uint8_t bpp, uint32_t stride, uint32_t handle) :Framebuffer(card, width, height) { uint32_t id; int r = drmModeAddFB(card.fd(), width, height, depth, bpp, stride, handle, &id); if (r) throw invalid_argument("fob"); set_id(id); }
ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format, uint32_t handles[], uint32_t pitches[], uint32_t offsets[]) : Framebuffer(card, width, height) { uint32_t id; int r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, handles, pitches, offsets, &id, 0); if (r) throw std::invalid_argument(string("Failed to create ExtFramebuffer: ") + strerror(r)); set_id(id); }
Framebuffer::Framebuffer(Card& card, uint32_t id) : DrmObject(card, id, DRM_MODE_OBJECT_FB) { auto fb = drmModeGetFB(card.fd(), id); m_width = fb->width; m_height = fb->height; drmModeFreeFB(fb); card.m_framebuffers.push_back(this); }
ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format, int fds[4], uint32_t pitches[4], uint32_t offsets[4]) : Framebuffer(card, width, height) { int r; const PixelFormatInfo& format_info = get_pixel_format_info(format); uint32_t handles[4] = { 0 }; for (int i = 0; i < format_info.num_planes; ++i) { r = drmPrimeFDToHandle(card.fd(), fds[i], &handles[i]); if (r) throw invalid_argument(string("drmPrimeFDToHandle: ") + strerror(errno)); } uint32_t id; r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, handles, pitches, offsets, &id, 0); if (r) throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno)); set_id(id); }
void main_gbm() { Card card; GbmDevice gdev(card); EglState egl(gdev.handle()); vector<unique_ptr<OutputHandler>> outputs; vector<Plane*> used_planes; float rot_mult = 1; for (auto pipe : card.get_connected_pipelines()) { auto connector = pipe.connector; auto crtc = pipe.crtc; auto mode = connector->get_default_mode(); Plane* plane = 0; if (s_support_planes) { for (Plane* p : crtc->get_possible_planes()) { if (find(used_planes.begin(), used_planes.end(), p) != used_planes.end()) continue; if (p->plane_type() != PlaneType::Overlay) continue; plane = p; break; } } if (plane) used_planes.push_back(plane); auto out = new OutputHandler(card, gdev, egl, connector, crtc, mode, plane, rot_mult); outputs.emplace_back(out); rot_mult *= 1.33; } for (auto& out : outputs) out->setup(); for (auto& out : outputs) out->start_flipping(); struct pollfd fds[2] = { }; fds[0].fd = 0; fds[0].events = POLLIN; fds[1].fd = card.fd(); fds[1].events = POLLIN; while (!s_need_exit || s_flip_pending) { int r = poll(fds, ARRAY_SIZE(fds), -1); FAIL_IF(r < 0, "poll error %d", r); if (fds[0].revents) s_need_exit = true; if (fds[1].revents) card.call_page_flip_handlers(); } }
GbmDevice(Card& card) { m_dev = gbm_create_device(card.fd()); FAIL_IF(!m_dev, "failed to create gbm device"); }
int main(int argc, char** argv) { string src_conn_name = "unknown"; string dst_conn_name = "hdmi"; PixelFormat pixfmt = PixelFormat::XRGB8888; OptionSet optionset = { Option("s|src=", [&](string s) { src_conn_name = s; }), Option("d|dst=", [&](string s) { dst_conn_name = s; }), Option("f|format=", [&](string s) { pixfmt = FourCCToPixelFormat(s); }), Option("h|help", [&]() { puts(usage_str); exit(-1); }), }; optionset.parse(argc, argv); if (optionset.params().size() > 0) { puts(usage_str); exit(-1); } VideoDevice vid("/dev/video11"); Card card; ResourceManager resman(card); auto src_conn = resman.reserve_connector(src_conn_name); auto src_crtc = resman.reserve_crtc(src_conn); uint32_t src_width = src_crtc->mode().hdisplay; uint32_t src_height = src_crtc->mode().vdisplay; printf("src %s, crtc %ux%u\n", src_conn->fullname().c_str(), src_width, src_height); auto dst_conn = resman.reserve_connector(dst_conn_name); auto dst_crtc = resman.reserve_crtc(dst_conn); auto dst_plane = resman.reserve_overlay_plane(dst_crtc, pixfmt); FAIL_IF(!dst_plane, "Plane not found"); uint32_t dst_width = min((uint32_t)dst_crtc->mode().hdisplay, src_width); uint32_t dst_height = min((uint32_t)dst_crtc->mode().vdisplay, src_height); printf("dst %s, crtc %ux%u, plane %ux%u\n", dst_conn->fullname().c_str(), dst_crtc->mode().hdisplay, dst_crtc->mode().vdisplay, dst_width, dst_height); for (int i = 0; i < CAMERA_BUF_QUEUE_SIZE; ++i) { auto fb = new DumbFramebuffer(card, src_width, src_height, pixfmt); s_fbs.push_back(fb); s_free_fbs.push_back(fb); } // get one fb for initial setup s_ready_fbs.push_back(s_free_fbs.back()); s_free_fbs.pop_back(); // This draws a moving bar to SRC display BarFlipState barflipper(card, src_crtc); barflipper.start_flipping(); // This shows the captures SRC frames on DST display WBFlipState wbflipper(card, dst_crtc, dst_plane); wbflipper.setup(0, 0, dst_width, dst_height); WBStreamer wb(vid.get_capture_streamer(), src_crtc, src_width, src_height, pixfmt); wb.start_streaming(); vector<pollfd> fds(3); fds[0].fd = 0; fds[0].events = POLLIN; fds[1].fd = wb.fd(); fds[1].events = POLLIN; fds[2].fd = card.fd(); fds[2].events = POLLIN; while (true) { int r = poll(fds.data(), fds.size(), -1); ASSERT(r > 0); if (fds[0].revents != 0) break; if (fds[1].revents) { fds[1].revents = 0; wb.Dequeue(); wbflipper.queue_next(); } if (fds[2].revents) { fds[2].revents = 0; card.call_page_flip_handlers(); wb.Queue(); } } printf("exiting...\n"); }