From eafc32efc0a6292678f7542e36b78a433ad8770a Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 5 Jan 2018 15:39:48 +0200 Subject: kmstest: Separate reservation phase from command line parsing In the new order the planes are not reserved before the whole command line is parsed. This way we know the color format of the framebuffer that is going to be on the reserved plane and we can select a plane that supports the format. After this patch kmstest makes no distinction between primary and overlay planes if atomic mode setting is supported. If no plane is specified then a default plane, matching the screen size is created. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- utils/kmstest.cpp | 224 +++++++++++++++++++++++------------------------------- 1 file changed, 97 insertions(+), 127 deletions(-) (limited to 'utils') diff --git a/utils/kmstest.cpp b/utils/kmstest.cpp index 0f763c0..62b103f 100644 --- a/utils/kmstest.cpp +++ b/utils/kmstest.cpp @@ -19,9 +19,10 @@ using namespace std; using namespace kms; struct PropInfo { - PropInfo(Property *p, uint64_t v) : prop(p), val(v) {} + PropInfo(string n, uint64_t v) : prop(NULL), name(n), val(v) {} Property *prop; + string name; uint64_t val; }; @@ -49,10 +50,8 @@ struct OutputInfo Connector* connector; Crtc* crtc; - Plane* primary_plane; Videomode mode; - bool user_set_crtc; - vector fbs; + vector legacy_fbs; vector planes; @@ -101,6 +100,16 @@ static void get_default_crtc(ResourceManager& resman, OutputInfo& output) EXIT("Could not find available crtc"); } + +static PlaneInfo *add_default_planeinfo(OutputInfo* output) +{ + output->planes.push_back(PlaneInfo { }); + PlaneInfo *ret = &output->planes.back(); + ret->w = output->mode.hdisplay; + ret->h = output->mode.vdisplay; + return ret; +} + static void parse_crtc(ResourceManager& resman, Card& card, const string& crtc_str, OutputInfo& output) { // @12:1920x1200i@60 @@ -259,14 +268,11 @@ static void parse_plane(ResourceManager& resman, Card& card, const string& plane pinfo.plane = planes[num]; } - pinfo.plane = resman.reserve_plane(pinfo.plane); - } else { - pinfo.plane = resman.reserve_overlay_plane(output.crtc); + auto plane = resman.reserve_plane(pinfo.plane); + if (!plane) + EXIT("Plane id %u is not available", pinfo.plane->id()); } - if (!pinfo.plane) - EXIT("Failed to find available plane"); - pinfo.w = stoul(sm[5]); pinfo.h = stoul(sm[6]); @@ -281,10 +287,9 @@ static void parse_plane(ResourceManager& resman, Card& card, const string& plane pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2; } -static void parse_prop(Card& card, const string& prop_str, vector &props, const DrmPropObject* propobj) +static void parse_prop(const string& prop_str, vector &props) { string name, val; - Property* prop; size_t split = prop_str.find("="); @@ -293,9 +298,14 @@ static void parse_prop(Card& card, const string& prop_str, vector &pro name = prop_str.substr(0, split); val = prop_str.substr(split+1); - prop = propobj->get_prop(name); - props.push_back(PropInfo(prop, stoull(val, 0, 0))); + props.push_back(PropInfo(name, stoull(val, 0, 0))); +} + +static void get_props(Card& card, vector &props, const DrmPropObject* propobj) +{ + for (auto& pi : props) + pi.prop = propobj->get_prop(pi.name); } static vector get_default_fb(Card& card, unsigned width, unsigned height) @@ -308,12 +318,19 @@ static vector get_default_fb(Card& card, unsigned width, unsigned return v; } -static vector parse_fb(Card& card, const string& fb_str, unsigned def_w, unsigned def_h) +static void parse_fb(Card& card, const string& fb_str, OutputInfo* output, PlaneInfo* pinfo) { - unsigned w = def_w; - unsigned h = def_h; + unsigned w, h; PixelFormat format = PixelFormat::XRGB8888; + if (pinfo) { + w = pinfo->w; + h = pinfo->h; + } else { + w = output->mode.hdisplay; + h = output->mode.vdisplay; + } + if (!fb_str.empty()) { // XXX the regexp is not quite correct // 400x400-NV12 @@ -338,7 +355,10 @@ static vector parse_fb(Card& card, const string& fb_str, unsigned for (unsigned i = 0; i < s_num_buffers; ++i) v.push_back(new DumbFramebuffer(card, w, h, format)); - return v; + if (pinfo) + pinfo->fbs = v; + else + output->legacy_fbs = v; } static void parse_view(const string& view_str, PlaneInfo& pinfo) @@ -509,27 +529,6 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, { vector outputs; - if (output_args.size() == 0) { - // no output args, show a pattern on all screens - for (Connector* conn : card.get_connectors()) { - if (!conn->connected()) - continue; - - OutputInfo output = { }; - output.connector = resman.reserve_connector(conn); - EXIT_IF(!output.connector, "Failed to reserve connector %s", conn->fullname().c_str()); - output.crtc = resman.reserve_crtc(conn); - EXIT_IF(!output.crtc, "Failed to reserve crtc for %s", conn->fullname().c_str()); - output.mode = output.connector->get_default_mode(); - - output.fbs = get_default_fb(card, output.mode.hdisplay, output.mode.vdisplay); - - outputs.push_back(output); - } - - return outputs; - } - OutputInfo* current_output = 0; PlaneInfo* current_plane = 0; @@ -558,8 +557,6 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, parse_crtc(resman, card, arg.arg, *current_output); - current_output->user_set_crtc = true; - current_plane = 0; break; @@ -578,8 +575,7 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, if (!current_output->crtc) get_default_crtc(resman, *current_output); - current_output->planes.push_back(PlaneInfo { }); - current_plane = ¤t_output->planes.back(); + current_plane = add_default_planeinfo(current_output); parse_plane(resman, card, arg.arg, *current_output, *current_plane); @@ -599,22 +595,10 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, if (!current_output->crtc) get_default_crtc(resman, *current_output); - int def_w, def_h; + if (!current_plane && card.has_atomic()) + current_plane = add_default_planeinfo(current_output); - if (current_plane) { - def_w = current_plane->w; - def_h = current_plane->h; - } else { - def_w = current_output->mode.hdisplay; - def_h = current_output->mode.vdisplay; - } - - auto fbs = parse_fb(card, arg.arg, def_w, def_h); - - if (current_plane) - current_plane->fbs = fbs; - else - current_output->fbs = fbs; + parse_fb(card, arg.arg, current_output, current_plane); break; } @@ -634,16 +618,11 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, EXIT("No object to which set the property"); if (current_plane) - parse_prop(card, arg.arg, current_plane->props, - current_plane->plane); + parse_prop(arg.arg, current_plane->props); else if (current_output->crtc) - parse_prop(card, arg.arg, - current_output->crtc_props, - current_output->crtc); + parse_prop(arg.arg, current_output->crtc_props); else if (current_output->connector) - parse_prop(card, arg.arg, - current_output->conn_props, - current_output->connector); + parse_prop(arg.arg, current_output->conn_props); else EXIT("no object"); @@ -652,20 +631,56 @@ static vector setups_to_outputs(Card& card, ResourceManager& resman, } } - // create default framebuffers if needed + if (outputs.empty()) { + // no outputs defined, show a pattern on all screens + for (Connector* conn : card.get_connectors()) { + if (!conn->connected()) + continue; + + OutputInfo output = { }; + output.connector = resman.reserve_connector(conn); + EXIT_IF(!output.connector, "Failed to reserve connector %s", conn->fullname().c_str()); + output.crtc = resman.reserve_crtc(conn); + EXIT_IF(!output.crtc, "Failed to reserve crtc for %s", conn->fullname().c_str()); + output.mode = output.connector->get_default_mode(); + + outputs.push_back(output); + } + } + for (OutputInfo& o : outputs) { - if (!o.crtc) { + get_props(card, o.conn_props, o.connector); + + if (!o.crtc) get_default_crtc(resman, o); - o.user_set_crtc = true; - } - if (o.fbs.empty() && o.user_set_crtc) - o.fbs = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay); + get_props(card, o.crtc_props, o.crtc); + + if (card.has_atomic()) { + if (o.planes.empty()) + add_default_planeinfo(&o); + } else { + if (o.legacy_fbs.empty()) + o.legacy_fbs = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay); + } for (PlaneInfo &p : o.planes) { if (p.fbs.empty()) p.fbs = get_default_fb(card, p.w, p.h); } + + for (PlaneInfo& p : o.planes) { + if (!p.plane) { + if (card.has_atomic()) + p.plane = resman.reserve_generic_plane(o.crtc, p.fbs[0]->format()); + else + p.plane = resman.reserve_overlay_plane(o.crtc, p.fbs[0]->format()); + + if (!p.plane) + EXIT("Failed to find available plane"); + } + get_props(card, p.props, p.plane); + } } return outputs; @@ -703,13 +718,11 @@ static void print_outputs(const vector& outputs) printf(" %s=%" PRIu64, prop.prop->name().c_str(), prop.val); - if (o.primary_plane) - printf(" (plane %u/@%u)", o.primary_plane->idx(), o.primary_plane->id()); printf(": %s\n", videomode_to_string(o.mode).c_str()); - if (!o.fbs.empty()) { - auto fb = o.fbs[0]; - printf(" Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(), - PixelFormatToFourCC(fb->format()).c_str()); + + if (!o.legacy_fbs.empty()) { + auto fb = o.legacy_fbs[0]; + printf(" (Fb %u %ux%u-%s)", fb->id(), fb->width(), fb->height(), PixelFormatToFourCC(fb->format()).c_str()); } for (unsigned j = 0; j < o.planes.size(); ++j) { @@ -731,7 +744,7 @@ static void print_outputs(const vector& outputs) static void draw_test_patterns(const vector& outputs) { for (const OutputInfo& o : outputs) { - for (auto fb : o.fbs) + for (auto fb : o.legacy_fbs) draw_test_pattern(*fb); for (const PlaneInfo& p : o.planes) @@ -757,8 +770,8 @@ static void set_crtcs_n_planes_legacy(Card& card, const vector& outp if (!o.conn_props.empty() || !o.crtc_props.empty()) printf("WARNING: properties not set without atomic modesetting"); - if (!o.fbs.empty()) { - auto fb = o.fbs[0]; + if (!o.legacy_fbs.empty()) { + auto fb = o.legacy_fbs[0]; int r = crtc->set_mode(conn, *fb, o.mode); if (r) printf("crtc->set_mode() failed for crtc %u: %s\n", @@ -800,15 +813,11 @@ static void set_crtcs_n_planes_atomic(Card& card, const vector& outp } // Disable unused planes - for (Plane* plane : card.get_planes()) { - //if (find_if(outputs.begin(), outputs.end(), [plane](const OutputInfo& o) { return o.primary_plane == plane; }) != outputs.end()) - // continue; - + for (Plane* plane : card.get_planes()) disable_req.add(plane, { { "FB_ID", 0 }, { "CRTC_ID", 0 }, }); - } r = disable_req.commit_sync(true); if (r) @@ -842,23 +851,6 @@ static void set_crtcs_n_planes_atomic(Card& card, const vector& outp for (const PropInfo &prop: o.crtc_props) req.add(crtc, prop.prop, prop.val); - if (!o.fbs.empty()) { - auto fb = o.fbs[0]; - - req.add(o.primary_plane, { - { "FB_ID", fb->id() }, - { "CRTC_ID", crtc->id() }, - { "SRC_X", 0 << 16 }, - { "SRC_Y", 0 << 16 }, - { "SRC_W", fb->width() << 16 }, - { "SRC_H", fb->height() << 16 }, - { "CRTC_X", 0 }, - { "CRTC_Y", 0 }, - { "CRTC_W", fb->width() }, - { "CRTC_H", fb->height() }, - }); - } - for (const PlaneInfo& p : o.planes) { auto fb = p.fbs[0]; @@ -968,16 +960,6 @@ private: { unsigned cur = frame_num % s_num_buffers; - if (!o.fbs.empty()) { - auto fb = o.fbs[cur]; - - draw_bar(fb, frame_num); - - req.add(o.primary_plane, { - { "FB_ID", fb->id() }, - }); - } - for (const PlaneInfo& p : o.planes) { auto fb = p.fbs[cur]; @@ -993,8 +975,8 @@ private: { unsigned cur = frame_num % s_num_buffers; - if (!o.fbs.empty()) { - auto fb = o.fbs[cur]; + if (!o.legacy_fbs.empty()) { + auto fb = o.legacy_fbs[cur]; draw_bar(fb, frame_num); @@ -1110,18 +1092,6 @@ int main(int argc, char **argv) vector outputs = setups_to_outputs(card, resman, output_args); - if (card.has_atomic()) { - for (OutputInfo& o : outputs) { - if (o.fbs.empty()) - continue; - - o.primary_plane = resman.reserve_primary_plane(o.crtc, o.fbs[0]->format()); - - if (!o.primary_plane) - EXIT("Could not get primary plane for crtc '%u'", o.crtc->id()); - } - } - if (!s_flip_mode) draw_test_patterns(outputs); -- cgit v1.2.3