]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android/external-libkmsxx.git/blobdiff - utils/kmstest.cpp
kmstest: fix bug in setups_to_outputs()
[android/external-libkmsxx.git] / utils / kmstest.cpp
index cc895e3dde9496bec8c9ff47fa01e45b4421c582..f12ed095712614e9b2976c7e859d63b2bd0047a3 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <kms++/kms++.h>
 #include <kms++/modedb.h>
+#include <kms++/mode_cvt.h>
 
 #include <kms++util/kms++util.h>
 
@@ -24,7 +25,7 @@ struct PlaneInfo
        unsigned w;
        unsigned h;
 
-       vector<DumbFramebuffer*> fbs;
+       vector<MappedFramebuffer*> fbs;
 };
 
 struct OutputInfo
@@ -35,7 +36,7 @@ struct OutputInfo
        Plane* primary_plane;
        Videomode mode;
        bool user_set_crtc;
-       vector<DumbFramebuffer*> fbs;
+       vector<MappedFramebuffer*> fbs;
 
        vector<PlaneInfo> planes;
 };
@@ -45,6 +46,9 @@ static bool s_use_cea;
 static unsigned s_num_buffers = 1;
 static bool s_flip_mode;
 static bool s_flip_sync;
+static bool s_cvt;
+static bool s_cvt_v2;
+static bool s_cvt_vid_opt;
 
 static set<Crtc*> s_used_crtcs;
 static set<Plane*> s_used_planes;
@@ -101,67 +105,127 @@ static void get_default_crtc(Card& card, OutputInfo& output)
 
 static void parse_crtc(Card& card, const string& crtc_str, OutputInfo& output)
 {
-       // @12:1920x1200@60
-       const regex mode_re("(?:(@?)(\\d+):)?"          // @12:
-                           "(?:(\\d+)x(\\d+)(i)?)"     // 1920x1200i
-                           "(?:@([\\d\\.]+))?");       // @60
+       // @12:1920x1200i@60
+       // @12:33000000,800/210/30/16/-,480/22/13/10/-,i
+
+       const regex modename_re("(?:(@?)(\\d+):)?"      // @12:
+                               "(?:(\\d+)x(\\d+)(i)?)" // 1920x1200i
+                               "(?:@([\\d\\.]+))?");   // @60
+
+       const regex modeline_re("(?:(@?)(\\d+):)?"                      // @12:
+                               "(\\d+),"                               // 33000000,
+                               "(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-]),"   // 800/210/30/16/-,
+                               "(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])"    // 480/22/13/10/-
+                               "(?:,([i]+))?"                          // ,i
+                               );
 
        smatch sm;
-       if (!regex_match(crtc_str, sm, mode_re))
-               EXIT("Failed to parse crtc option '%s'", crtc_str.c_str());
+       if (regex_match(crtc_str, sm, modename_re)) {
+               if (sm[2].matched) {
+                       bool use_id = sm[1].length() == 1;
+                       unsigned num = stoul(sm[2].str());
 
-       if (sm[2].matched) {
-               bool use_id = sm[1].length() == 1;
-               unsigned num = stoul(sm[2].str());
+                       if (use_id) {
+                               Crtc* c = card.get_crtc(num);
+                               if (!c)
+                                       EXIT("Bad crtc id '%u'", num);
 
-               if (use_id) {
-                       Crtc* c = card.get_crtc(num);
-                       if (!c)
-                               EXIT("Bad crtc id '%u'", num);
+                               output.crtc = c;
+                       } else {
+                               auto crtcs = card.get_crtcs();
 
-                       output.crtc = c;
-               } else {
-                       auto crtcs = card.get_crtcs();
+                               if (num >= crtcs.size())
+                                       EXIT("Bad crtc number '%u'", num);
 
-                       if (num >= crtcs.size())
-                               EXIT("Bad crtc number '%u'", num);
+                               output.crtc = crtcs[num];
+                       }
+               } else {
+                       output.crtc = output.connector->get_current_crtc();
+               }
 
-                       output.crtc = crtcs[num];
+               unsigned w = stoul(sm[3]);
+               unsigned h = stoul(sm[4]);
+               bool ilace = sm[5].matched ? true : false;
+               float refresh = sm[6].matched ? stof(sm[6]) : 0;
+
+               if (s_cvt) {
+                       output.mode = videomode_from_cvt(w, h, refresh, ilace, s_cvt_v2, s_cvt_vid_opt);
+               } else if (s_use_dmt) {
+                       try {
+                               output.mode = find_dmt(w, h, refresh, ilace);
+                       } catch (exception& e) {
+                               EXIT("Mode not found from DMT tables\n");
+                       }
+               } else if (s_use_cea) {
+                       try {
+                               output.mode = find_cea(w, h, refresh, ilace);
+                       } catch (exception& e) {
+                               EXIT("Mode not found from CEA tables\n");
+                       }
+               } else {
+                       try {
+                               output.mode = output.connector->get_mode(w, h, refresh, ilace);
+                       } catch (exception& e) {
+                               EXIT("Mode not found from the connector\n");
+                       }
                }
-       } else {
-               output.crtc = output.connector->get_current_crtc();
-       }
+       } else if (regex_match(crtc_str, sm, modeline_re)) {
+               if (sm[2].matched) {
+                       bool use_id = sm[1].length() == 1;
+                       unsigned num = stoul(sm[2].str());
 
-       unsigned w = stoul(sm[3]);
-       unsigned h = stoul(sm[4]);
-       bool ilace = sm[5].matched ? true : false;
-       float refresh = sm[6].matched ? stof(sm[6]) : 0;
+                       if (use_id) {
+                               Crtc* c = card.get_crtc(num);
+                               if (!c)
+                                       EXIT("Bad crtc id '%u'", num);
 
-       bool found_mode = false;
+                               output.crtc = c;
+                       } else {
+                               auto crtcs = card.get_crtcs();
 
-       try {
-               output.mode = output.connector->get_mode(w, h, refresh, ilace);
-               found_mode = true;
-       } catch (exception& e) { }
+                               if (num >= crtcs.size())
+                                       EXIT("Bad crtc number '%u'", num);
 
-       if (!found_mode && s_use_dmt) {
-               try {
-                       output.mode = find_dmt(w, h, refresh, ilace);
-                       found_mode = true;
-                       printf("Found mode from DMT\n");
-               } catch (exception& e) { }
-       }
+                               output.crtc = crtcs[num];
+                       }
+               } else {
+                       output.crtc = output.connector->get_current_crtc();
+               }
 
-       if (!found_mode && s_use_cea) {
-               try {
-                       output.mode = find_cea(w, h, refresh, ilace);
-                       found_mode = true;
-                       printf("Found mode from CEA\n");
-               } catch (exception& e) { }
+               unsigned clock = stoul(sm[3]);
+
+               unsigned hact = stoul(sm[4]);
+               unsigned hfp = stoul(sm[5]);
+               unsigned hsw = stoul(sm[6]);
+               unsigned hbp = stoul(sm[7]);
+               bool h_pos_sync = sm[8] == "+" ? true : false;
+
+               unsigned vact = stoul(sm[9]);
+               unsigned vfp = stoul(sm[10]);
+               unsigned vsw = stoul(sm[11]);
+               unsigned vbp = stoul(sm[12]);
+               bool v_pos_sync = sm[13] == "+" ? true : false;
+
+               output.mode = videomode_from_timings(clock / 1000, hact, hfp, hsw, hbp, vact, vfp, vsw, vbp);
+               output.mode.set_hsync(h_pos_sync ? SyncPolarity::Positive : SyncPolarity::Negative);
+               output.mode.set_vsync(v_pos_sync ? SyncPolarity::Positive : SyncPolarity::Negative);
+
+               if (sm[14].matched) {
+                       for (int i = 0; i < sm[14].length(); ++i) {
+                               char f = string(sm[14])[i];
+
+                               switch (f) {
+                               case 'i':
+                                       output.mode.set_interlace(true);
+                                       break;
+                               default:
+                                       EXIT("Bad mode flag %c", f);
+                               }
+                       }
+               }
+       } else {
+               EXIT("Failed to parse crtc option '%s'", crtc_str.c_str());
        }
-
-       if (!found_mode)
-               throw invalid_argument("Mode not found");
 }
 
 static void parse_plane(Card& card, const string& plane_str, const OutputInfo& output, PlaneInfo& pinfo)
@@ -224,9 +288,9 @@ static void parse_plane(Card& card, const string& plane_str, const OutputInfo& o
                pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2;
 }
 
-static vector<DumbFramebuffer*> get_default_fb(Card& card, unsigned width, unsigned height)
+static vector<MappedFramebuffer*> get_default_fb(Card& card, unsigned width, unsigned height)
 {
-       vector<DumbFramebuffer*> v;
+       vector<MappedFramebuffer*> v;
 
        for (unsigned i = 0; i < s_num_buffers; ++i)
                v.push_back(new DumbFramebuffer(card, width, height, PixelFormat::XRGB8888));
@@ -234,7 +298,7 @@ static vector<DumbFramebuffer*> get_default_fb(Card& card, unsigned width, unsig
        return v;
 }
 
-static vector<DumbFramebuffer*> parse_fb(Card& card, const string& fb_str, unsigned def_w, unsigned def_h)
+static vector<MappedFramebuffer*> parse_fb(Card& card, const string& fb_str, unsigned def_w, unsigned def_h)
 {
        unsigned w = def_w;
        unsigned h = def_h;
@@ -259,7 +323,7 @@ static vector<DumbFramebuffer*> parse_fb(Card& card, const string& fb_str, unsig
                        format = FourCCToPixelFormat(sm[3]);
        }
 
-       vector<DumbFramebuffer*> v;
+       vector<MappedFramebuffer*> v;
 
        for (unsigned i = 0; i < s_num_buffers; ++i)
                v.push_back(new DumbFramebuffer(card, w, h, format));
@@ -274,10 +338,13 @@ static const char* usage_str =
                "      --device=DEVICE       DEVICE is the path to DRM card to open\n"
                "  -c, --connector=CONN      CONN is <connector>\n"
                "  -r, --crtc=CRTC           CRTC is [<crtc>:]<w>x<h>[@<Hz>]\n"
+               "                            or\n"
+               "                            [<crtc>:]<pclk>,<hact>/<hfp>/<hsw>/<hbp>/<hsp>,<vact>/<vfp>/<vsw>/<vbp>/<vsp>[,i]\n"
                "  -p, --plane=PLANE         PLANE is [<plane>:][<x>,<y>-]<w>x<h>\n"
                "  -f, --fb=FB               FB is [<w>x<h>][-][<4cc>]\n"
                "      --dmt                 Search for the given mode from DMT tables\n"
                "      --cea                 Search for the given mode from CEA tables\n"
+               "      --cvt=CVT             Create videomode with CVT. CVT is 'v1', 'v2' or 'v2o'\n"
                "      --flip                Do page flipping for each output\n"
                "      --sync                Synchronize page flipping\n"
                "\n"
@@ -366,6 +433,19 @@ static vector<Arg> parse_cmdline(int argc, char **argv)
                {
                        s_flip_sync = true;
                }),
+               Option("|cvt=", [&](string s)
+               {
+                       if (s == "v1")
+                               s_cvt = true;
+                       else if (s == "v2")
+                               s_cvt = s_cvt_v2 = true;
+                       else if (s == "v2o")
+                               s_cvt = s_cvt_v2 = s_cvt_vid_opt = true;
+                       else {
+                               usage();
+                               exit(-1);
+                       }
+               }),
                Option("h|help", [&]()
                {
                        usage();
@@ -497,7 +577,7 @@ static vector<OutputInfo> setups_to_outputs(Card& card, const vector<Arg>& outpu
        // create default framebuffers if needed
        for (OutputInfo& o : outputs) {
                if (!o.crtc) {
-                       get_default_crtc(card, *current_output);
+                       get_default_crtc(card, o);
                        o.user_set_crtc = true;
                }
 
@@ -604,20 +684,20 @@ static void set_crtcs_n_planes(Card& card, const vector<OutputInfo>& outputs)
                auto conn = o.connector;
                auto crtc = o.crtc;
 
-               if (!o.fbs.empty()) {
-                       auto fb = o.fbs[0];
+               blobs.emplace_back(o.mode.to_blob(card));
+               Blob* mode_blob = blobs.back().get();
 
-                       blobs.emplace_back(o.mode.to_blob(card));
-                       Blob* mode_blob = blobs.back().get();
+               req.add(conn, {
+                               { "CRTC_ID", crtc->id() },
+                       });
 
-                       req.add(conn, {
-                                       { "CRTC_ID", crtc->id() },
-                               });
+               req.add(crtc, {
+                               { "ACTIVE", 1 },
+                               { "MODE_ID", mode_blob->id() },
+                       });
 
-                       req.add(crtc, {
-                                       { "ACTIVE", 1 },
-                                       { "MODE_ID", mode_blob->id() },
-                               });
+               if (!o.fbs.empty()) {
+                       auto fb = o.fbs[0];
 
                        req.add(o.primary_plane, {
                                        { "FB_ID", fb->id() },
@@ -704,12 +784,12 @@ private:
                queue_next();
        }
 
-       static unsigned get_bar_pos(DumbFramebuffer* fb, unsigned frame_num)
+       static unsigned get_bar_pos(MappedFramebuffer* fb, unsigned frame_num)
        {
                return (frame_num * bar_speed) % (fb->width() - bar_width + 1);
        }
 
-       static void draw_bar(DumbFramebuffer* fb, unsigned frame_num)
+       static void draw_bar(MappedFramebuffer* fb, unsigned frame_num)
        {
                int old_xpos = frame_num < s_num_buffers ? -1 : get_bar_pos(fb, frame_num - s_num_buffers);
                int new_xpos = get_bar_pos(fb, frame_num);
@@ -859,9 +939,11 @@ int main(int argc, char **argv)
 
        vector<OutputInfo> outputs = setups_to_outputs(card, output_args);
 
+       ResourceManager resman(card);
+
        if (card.has_atomic()) {
                for (OutputInfo& o : outputs) {
-                       o.primary_plane = o.crtc->get_primary_plane();
+                       o.primary_plane = resman.reserve_primary_plane(o.crtc);
 
                        if (!o.fbs.empty() && !o.primary_plane)
                                EXIT("Could not get primary plane for crtc '%u'", o.crtc->id());