testpat: atomic commit
[android/external-libkmsxx.git] / utils / testpat.cpp
index 5f1095cb62cf7da2dccbcb284c35d599df2a5d89..6aa658345e6cea14855350cf33fb20e2d870842f 100644 (file)
@@ -30,6 +30,7 @@ struct OutputInfo
        Connector* connector;
 
        Crtc* crtc;
+       Plane* primary_plane;
        Videomode mode;
        bool user_set_crtc;
        vector<DumbFramebuffer*> fbs;
@@ -552,7 +553,10 @@ static void print_outputs(const vector<OutputInfo>& outputs)
 
                printf("Connector %u/@%u: %s\n", o.connector->id(), o.connector->idx(),
                       o.connector->fullname().c_str());
-               printf("  Crtc %u/@%u: %ux%u-%u (%s)\n", o.crtc->id(), o.crtc->idx(),
+               printf("  Crtc %u/@%u", o.crtc->id(), o.crtc->idx());
+               if (o.primary_plane)
+                       printf(" (plane %u/@%u)", o.primary_plane->id(), o.primary_plane->idx());
+               printf(": %ux%u-%u (%s)\n",
                       o.mode.hdisplay, o.mode.vdisplay, o.mode.vrefresh,
                       videomode_to_string(o.mode).c_str());
                if (!o.fbs.empty()) {
@@ -584,7 +588,7 @@ static void draw_test_patterns(const vector<OutputInfo>& outputs)
        }
 }
 
-static void set_crtcs_n_planes(Card& card, const vector<OutputInfo>& outputs)
+static void set_crtcs_n_planes_legacy(Card& card, const vector<OutputInfo>& outputs)
 {
        for (const OutputInfo& o : outputs) {
                auto conn = o.connector;
@@ -610,6 +614,75 @@ static void set_crtcs_n_planes(Card& card, const vector<OutputInfo>& outputs)
        }
 }
 
+static void set_crtcs_n_planes(Card& card, const vector<OutputInfo>& outputs)
+{
+       // Keep blobs here so that we keep ref to them until we have committed the req
+       vector<unique_ptr<Blob>> blobs;
+
+       AtomicReq req(card);
+
+       for (const OutputInfo& o : 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();
+
+                       req.add(conn, {
+                                       { "CRTC_ID", crtc->id() },
+                               });
+
+                       req.add(crtc, {
+                                       { "ACTIVE", 1 },
+                                       { "MODE_ID", mode_blob->id() },
+                               });
+
+                       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];
+
+                       req.add(p.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", p.x },
+                                       { "CRTC_Y", p.y },
+                                       { "CRTC_W", p.w },
+                                       { "CRTC_H", p.h },
+                               });
+               }
+       }
+
+       int r;
+
+       r = req.test(true);
+       if (r)
+               EXIT("Atomic test failed: %d\n", r);
+
+       r = req.commit_sync(true);
+       if (r)
+               EXIT("Atomic commit failed: %d\n", r);
+}
+
 int main(int argc, char **argv)
 {
        vector<Arg> output_args = parse_cmdline(argc, argv);
@@ -618,11 +691,23 @@ int main(int argc, char **argv)
 
        vector<OutputInfo> outputs = setups_to_outputs(card, output_args);
 
+       if (card.has_atomic()) {
+               for (OutputInfo& o : outputs) {
+                       o.primary_plane = o.crtc->get_primary_plane();
+
+                       if (!o.fbs.empty() && !o.primary_plane)
+                               EXIT("Could not get primary plane for crtc '%u'", o.crtc->id());
+               }
+       }
+
        draw_test_patterns(outputs);
 
        print_outputs(outputs);
 
-       set_crtcs_n_planes(card, outputs);
+       if (card.has_atomic())
+               set_crtcs_n_planes(card, outputs);
+       else
+               set_crtcs_n_planes_legacy(card, outputs);
 
        printf("press enter to exit\n");