kmstest: Separate reservation phase from command line parsing
authorJyri Sarha <jsarha@ti.com>
Fri, 5 Jan 2018 13:39:48 +0000 (15:39 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 5 Jan 2018 13:48:53 +0000 (15:48 +0200)
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 <jsarha@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
utils/kmstest.cpp

index 0f763c0063b2a11fad2e5bb23e28473c90baf2c4..62b103f642a9d5d223f7bd519aeeb88d3f90a278 100644 (file)
@@ -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<Framebuffer*> fbs;
+       vector<Framebuffer*> legacy_fbs;
 
        vector<PlaneInfo> 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<PropInfo> &props, const DrmPropObject* propobj)
+static void parse_prop(const string& prop_str, vector<PropInfo> &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<PropInfo> &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<PropInfo> &props, const DrmPropObject* propobj)
+{
+       for (auto& pi : props)
+               pi.prop = propobj->get_prop(pi.name);
 }
 
 static vector<Framebuffer*> get_default_fb(Card& card, unsigned width, unsigned height)
@@ -308,12 +318,19 @@ static vector<Framebuffer*> get_default_fb(Card& card, unsigned width, unsigned
        return v;
 }
 
-static vector<Framebuffer*> 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<Framebuffer*> 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<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
 {
        vector<OutputInfo> 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<OutputInfo> 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<OutputInfo> 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 = &current_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<OutputInfo> 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<OutputInfo> 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<OutputInfo> 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<OutputInfo>& 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<OutputInfo>& outputs)
 static void draw_test_patterns(const vector<OutputInfo>& 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<OutputInfo>& 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<OutputInfo>& 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<OutputInfo>& 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<OutputInfo> 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);