aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJyri Sarha2018-01-05 07:39:48 -0600
committerTomi Valkeinen2018-01-05 07:48:53 -0600
commiteafc32efc0a6292678f7542e36b78a433ad8770a (patch)
tree396fceb999ec1e1162ad49e7f7fe455a3ad6a890
parent141d80881d1c759d43276375e6381537cdf8d0a4 (diff)
downloadexternal-libkmsxx-eafc32efc0a6292678f7542e36b78a433ad8770a.tar.gz
external-libkmsxx-eafc32efc0a6292678f7542e36b78a433ad8770a.tar.xz
external-libkmsxx-eafc32efc0a6292678f7542e36b78a433ad8770a.zip
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 <jsarha@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--utils/kmstest.cpp224
1 files changed, 97 insertions, 127 deletions
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;
19using namespace kms; 19using namespace kms;
20 20
21struct PropInfo { 21struct PropInfo {
22 PropInfo(Property *p, uint64_t v) : prop(p), val(v) {} 22 PropInfo(string n, uint64_t v) : prop(NULL), name(n), val(v) {}
23 23
24 Property *prop; 24 Property *prop;
25 string name;
25 uint64_t val; 26 uint64_t val;
26}; 27};
27 28
@@ -49,10 +50,8 @@ struct OutputInfo
49 Connector* connector; 50 Connector* connector;
50 51
51 Crtc* crtc; 52 Crtc* crtc;
52 Plane* primary_plane;
53 Videomode mode; 53 Videomode mode;
54 bool user_set_crtc; 54 vector<Framebuffer*> legacy_fbs;
55 vector<Framebuffer*> fbs;
56 55
57 vector<PlaneInfo> planes; 56 vector<PlaneInfo> planes;
58 57
@@ -101,6 +100,16 @@ static void get_default_crtc(ResourceManager& resman, OutputInfo& output)
101 EXIT("Could not find available crtc"); 100 EXIT("Could not find available crtc");
102} 101}
103 102
103
104static PlaneInfo *add_default_planeinfo(OutputInfo* output)
105{
106 output->planes.push_back(PlaneInfo { });
107 PlaneInfo *ret = &output->planes.back();
108 ret->w = output->mode.hdisplay;
109 ret->h = output->mode.vdisplay;
110 return ret;
111}
112
104static void parse_crtc(ResourceManager& resman, Card& card, const string& crtc_str, OutputInfo& output) 113static void parse_crtc(ResourceManager& resman, Card& card, const string& crtc_str, OutputInfo& output)
105{ 114{
106 // @12:1920x1200i@60 115 // @12:1920x1200i@60
@@ -259,14 +268,11 @@ static void parse_plane(ResourceManager& resman, Card& card, const string& plane
259 pinfo.plane = planes[num]; 268 pinfo.plane = planes[num];
260 } 269 }
261 270
262 pinfo.plane = resman.reserve_plane(pinfo.plane); 271 auto plane = resman.reserve_plane(pinfo.plane);
263 } else { 272 if (!plane)
264 pinfo.plane = resman.reserve_overlay_plane(output.crtc); 273 EXIT("Plane id %u is not available", pinfo.plane->id());
265 } 274 }
266 275
267 if (!pinfo.plane)
268 EXIT("Failed to find available plane");
269
270 pinfo.w = stoul(sm[5]); 276 pinfo.w = stoul(sm[5]);
271 pinfo.h = stoul(sm[6]); 277 pinfo.h = stoul(sm[6]);
272 278
@@ -281,10 +287,9 @@ static void parse_plane(ResourceManager& resman, Card& card, const string& plane
281 pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2; 287 pinfo.y = output.mode.vdisplay / 2 - pinfo.h / 2;
282} 288}
283 289
284static void parse_prop(Card& card, const string& prop_str, vector<PropInfo> &props, const DrmPropObject* propobj) 290static void parse_prop(const string& prop_str, vector<PropInfo> &props)
285{ 291{
286 string name, val; 292 string name, val;
287 Property* prop;
288 293
289 size_t split = prop_str.find("="); 294 size_t split = prop_str.find("=");
290 295
@@ -293,9 +298,14 @@ static void parse_prop(Card& card, const string& prop_str, vector<PropInfo> &pro
293 298
294 name = prop_str.substr(0, split); 299 name = prop_str.substr(0, split);
295 val = prop_str.substr(split+1); 300 val = prop_str.substr(split+1);
296 prop = propobj->get_prop(name);
297 301
298 props.push_back(PropInfo(prop, stoull(val, 0, 0))); 302 props.push_back(PropInfo(name, stoull(val, 0, 0)));
303}
304
305static void get_props(Card& card, vector<PropInfo> &props, const DrmPropObject* propobj)
306{
307 for (auto& pi : props)
308 pi.prop = propobj->get_prop(pi.name);
299} 309}
300 310
301static vector<Framebuffer*> get_default_fb(Card& card, unsigned width, unsigned height) 311static 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
308 return v; 318 return v;
309} 319}
310 320
311static vector<Framebuffer*> parse_fb(Card& card, const string& fb_str, unsigned def_w, unsigned def_h) 321static void parse_fb(Card& card, const string& fb_str, OutputInfo* output, PlaneInfo* pinfo)
312{ 322{
313 unsigned w = def_w; 323 unsigned w, h;
314 unsigned h = def_h;
315 PixelFormat format = PixelFormat::XRGB8888; 324 PixelFormat format = PixelFormat::XRGB8888;
316 325
326 if (pinfo) {
327 w = pinfo->w;
328 h = pinfo->h;
329 } else {
330 w = output->mode.hdisplay;
331 h = output->mode.vdisplay;
332 }
333
317 if (!fb_str.empty()) { 334 if (!fb_str.empty()) {
318 // XXX the regexp is not quite correct 335 // XXX the regexp is not quite correct
319 // 400x400-NV12 336 // 400x400-NV12
@@ -338,7 +355,10 @@ static vector<Framebuffer*> parse_fb(Card& card, const string& fb_str, unsigned
338 for (unsigned i = 0; i < s_num_buffers; ++i) 355 for (unsigned i = 0; i < s_num_buffers; ++i)
339 v.push_back(new DumbFramebuffer(card, w, h, format)); 356 v.push_back(new DumbFramebuffer(card, w, h, format));
340 357
341 return v; 358 if (pinfo)
359 pinfo->fbs = v;
360 else
361 output->legacy_fbs = v;
342} 362}
343 363
344static void parse_view(const string& view_str, PlaneInfo& pinfo) 364static void parse_view(const string& view_str, PlaneInfo& pinfo)
@@ -509,27 +529,6 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
509{ 529{
510 vector<OutputInfo> outputs; 530 vector<OutputInfo> outputs;
511 531
512 if (output_args.size() == 0) {
513 // no output args, show a pattern on all screens
514 for (Connector* conn : card.get_connectors()) {
515 if (!conn->connected())
516 continue;
517
518 OutputInfo output = { };
519 output.connector = resman.reserve_connector(conn);
520 EXIT_IF(!output.connector, "Failed to reserve connector %s", conn->fullname().c_str());
521 output.crtc = resman.reserve_crtc(conn);
522 EXIT_IF(!output.crtc, "Failed to reserve crtc for %s", conn->fullname().c_str());
523 output.mode = output.connector->get_default_mode();
524
525 output.fbs = get_default_fb(card, output.mode.hdisplay, output.mode.vdisplay);
526
527 outputs.push_back(output);
528 }
529
530 return outputs;
531 }
532
533 OutputInfo* current_output = 0; 532 OutputInfo* current_output = 0;
534 PlaneInfo* current_plane = 0; 533 PlaneInfo* current_plane = 0;
535 534
@@ -558,8 +557,6 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
558 557
559 parse_crtc(resman, card, arg.arg, *current_output); 558 parse_crtc(resman, card, arg.arg, *current_output);
560 559
561 current_output->user_set_crtc = true;
562
563 current_plane = 0; 560 current_plane = 0;
564 561
565 break; 562 break;
@@ -578,8 +575,7 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
578 if (!current_output->crtc) 575 if (!current_output->crtc)
579 get_default_crtc(resman, *current_output); 576 get_default_crtc(resman, *current_output);
580 577
581 current_output->planes.push_back(PlaneInfo { }); 578 current_plane = add_default_planeinfo(current_output);
582 current_plane = &current_output->planes.back();
583 579
584 parse_plane(resman, card, arg.arg, *current_output, *current_plane); 580 parse_plane(resman, card, arg.arg, *current_output, *current_plane);
585 581
@@ -599,22 +595,10 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
599 if (!current_output->crtc) 595 if (!current_output->crtc)
600 get_default_crtc(resman, *current_output); 596 get_default_crtc(resman, *current_output);
601 597
602 int def_w, def_h; 598 if (!current_plane && card.has_atomic())
599 current_plane = add_default_planeinfo(current_output);
603 600
604 if (current_plane) { 601 parse_fb(card, arg.arg, current_output, current_plane);
605 def_w = current_plane->w;
606 def_h = current_plane->h;
607 } else {
608 def_w = current_output->mode.hdisplay;
609 def_h = current_output->mode.vdisplay;
610 }
611
612 auto fbs = parse_fb(card, arg.arg, def_w, def_h);
613
614 if (current_plane)
615 current_plane->fbs = fbs;
616 else
617 current_output->fbs = fbs;
618 602
619 break; 603 break;
620 } 604 }
@@ -634,16 +618,11 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
634 EXIT("No object to which set the property"); 618 EXIT("No object to which set the property");
635 619
636 if (current_plane) 620 if (current_plane)
637 parse_prop(card, arg.arg, current_plane->props, 621 parse_prop(arg.arg, current_plane->props);
638 current_plane->plane);
639 else if (current_output->crtc) 622 else if (current_output->crtc)
640 parse_prop(card, arg.arg, 623 parse_prop(arg.arg, current_output->crtc_props);
641 current_output->crtc_props,
642 current_output->crtc);
643 else if (current_output->connector) 624 else if (current_output->connector)
644 parse_prop(card, arg.arg, 625 parse_prop(arg.arg, current_output->conn_props);
645 current_output->conn_props,
646 current_output->connector);
647 else 626 else
648 EXIT("no object"); 627 EXIT("no object");
649 628
@@ -652,20 +631,56 @@ static vector<OutputInfo> setups_to_outputs(Card& card, ResourceManager& resman,
652 } 631 }
653 } 632 }
654 633
655 // create default framebuffers if needed 634 if (outputs.empty()) {
635 // no outputs defined, show a pattern on all screens
636 for (Connector* conn : card.get_connectors()) {
637 if (!conn->connected())
638 continue;
639
640 OutputInfo output = { };
641 output.connector = resman.reserve_connector(conn);
642 EXIT_IF(!output.connector, "Failed to reserve connector %s", conn->fullname().c_str());
643 output.crtc = resman.reserve_crtc(conn);
644 EXIT_IF(!output.crtc, "Failed to reserve crtc for %s", conn->fullname().c_str());
645 output.mode = output.connector->get_default_mode();
646
647 outputs.push_back(output);
648 }
649 }
650
656 for (OutputInfo& o : outputs) { 651 for (OutputInfo& o : outputs) {
657 if (!o.crtc) { 652 get_props(card, o.conn_props, o.connector);
653
654 if (!o.crtc)
658 get_default_crtc(resman, o); 655 get_default_crtc(resman, o);
659 o.user_set_crtc = true;
660 }
661 656
662 if (o.fbs.empty() && o.user_set_crtc) 657 get_props(card, o.crtc_props, o.crtc);
663 o.fbs = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay); 658
659 if (card.has_atomic()) {
660 if (o.planes.empty())
661 add_default_planeinfo(&o);
662 } else {
663 if (o.legacy_fbs.empty())
664 o.legacy_fbs = get_default_fb(card, o.mode.hdisplay, o.mode.vdisplay);
665 }
664 666
665 for (PlaneInfo &p : o.planes) { 667 for (PlaneInfo &p : o.planes) {
666 if (p.fbs.empty()) 668 if (p.fbs.empty())
667 p.fbs = get_default_fb(card, p.w, p.h); 669 p.fbs = get_default_fb(card, p.w, p.h);
668 } 670 }
671
672 for (PlaneInfo& p : o.planes) {
673 if (!p.plane) {
674 if (card.has_atomic())
675 p.plane = resman.reserve_generic_plane(o.crtc, p.fbs[0]->format());
676 else
677 p.plane = resman.reserve_overlay_plane(o.crtc, p.fbs[0]->format());
678
679 if (!p.plane)
680 EXIT("Failed to find available plane");
681 }
682 get_props(card, p.props, p.plane);
683 }
669 } 684 }
670 685
671 return outputs; 686 return outputs;
@@ -703,13 +718,11 @@ static void print_outputs(const vector<OutputInfo>& outputs)
703 printf(" %s=%" PRIu64, prop.prop->name().c_str(), 718 printf(" %s=%" PRIu64, prop.prop->name().c_str(),
704 prop.val); 719 prop.val);
705 720
706 if (o.primary_plane)
707 printf(" (plane %u/@%u)", o.primary_plane->idx(), o.primary_plane->id());
708 printf(": %s\n", videomode_to_string(o.mode).c_str()); 721 printf(": %s\n", videomode_to_string(o.mode).c_str());
709 if (!o.fbs.empty()) { 722
710 auto fb = o.fbs[0]; 723 if (!o.legacy_fbs.empty()) {
711 printf(" Fb %u %ux%u-%s\n", fb->id(), fb->width(), fb->height(), 724 auto fb = o.legacy_fbs[0];
712 PixelFormatToFourCC(fb->format()).c_str()); 725 printf(" (Fb %u %ux%u-%s)", fb->id(), fb->width(), fb->height(), PixelFormatToFourCC(fb->format()).c_str());
713 } 726 }
714 727
715 for (unsigned j = 0; j < o.planes.size(); ++j) { 728 for (unsigned j = 0; j < o.planes.size(); ++j) {
@@ -731,7 +744,7 @@ static void print_outputs(const vector<OutputInfo>& outputs)
731static void draw_test_patterns(const vector<OutputInfo>& outputs) 744static void draw_test_patterns(const vector<OutputInfo>& outputs)
732{ 745{
733 for (const OutputInfo& o : outputs) { 746 for (const OutputInfo& o : outputs) {
734 for (auto fb : o.fbs) 747 for (auto fb : o.legacy_fbs)
735 draw_test_pattern(*fb); 748 draw_test_pattern(*fb);
736 749
737 for (const PlaneInfo& p : o.planes) 750 for (const PlaneInfo& p : o.planes)
@@ -757,8 +770,8 @@ static void set_crtcs_n_planes_legacy(Card& card, const vector<OutputInfo>& outp
757 if (!o.conn_props.empty() || !o.crtc_props.empty()) 770 if (!o.conn_props.empty() || !o.crtc_props.empty())
758 printf("WARNING: properties not set without atomic modesetting"); 771 printf("WARNING: properties not set without atomic modesetting");
759 772
760 if (!o.fbs.empty()) { 773 if (!o.legacy_fbs.empty()) {
761 auto fb = o.fbs[0]; 774 auto fb = o.legacy_fbs[0];
762 int r = crtc->set_mode(conn, *fb, o.mode); 775 int r = crtc->set_mode(conn, *fb, o.mode);
763 if (r) 776 if (r)
764 printf("crtc->set_mode() failed for crtc %u: %s\n", 777 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
800 } 813 }
801 814
802 // Disable unused planes 815 // Disable unused planes
803 for (Plane* plane : card.get_planes()) { 816 for (Plane* plane : card.get_planes())
804 //if (find_if(outputs.begin(), outputs.end(), [plane](const OutputInfo& o) { return o.primary_plane == plane; }) != outputs.end())
805 // continue;
806
807 disable_req.add(plane, { 817 disable_req.add(plane, {
808 { "FB_ID", 0 }, 818 { "FB_ID", 0 },
809 { "CRTC_ID", 0 }, 819 { "CRTC_ID", 0 },
810 }); 820 });
811 }
812 821
813 r = disable_req.commit_sync(true); 822 r = disable_req.commit_sync(true);
814 if (r) 823 if (r)
@@ -842,23 +851,6 @@ static void set_crtcs_n_planes_atomic(Card& card, const vector<OutputInfo>& outp
842 for (const PropInfo &prop: o.crtc_props) 851 for (const PropInfo &prop: o.crtc_props)
843 req.add(crtc, prop.prop, prop.val); 852 req.add(crtc, prop.prop, prop.val);
844 853
845 if (!o.fbs.empty()) {
846 auto fb = o.fbs[0];
847
848 req.add(o.primary_plane, {
849 { "FB_ID", fb->id() },
850 { "CRTC_ID", crtc->id() },
851 { "SRC_X", 0 << 16 },
852 { "SRC_Y", 0 << 16 },
853 { "SRC_W", fb->width() << 16 },
854 { "SRC_H", fb->height() << 16 },
855 { "CRTC_X", 0 },
856 { "CRTC_Y", 0 },
857 { "CRTC_W", fb->width() },
858 { "CRTC_H", fb->height() },
859 });
860 }
861
862 for (const PlaneInfo& p : o.planes) { 854 for (const PlaneInfo& p : o.planes) {
863 auto fb = p.fbs[0]; 855 auto fb = p.fbs[0];
864 856
@@ -968,16 +960,6 @@ private:
968 { 960 {
969 unsigned cur = frame_num % s_num_buffers; 961 unsigned cur = frame_num % s_num_buffers;
970 962
971 if (!o.fbs.empty()) {
972 auto fb = o.fbs[cur];
973
974 draw_bar(fb, frame_num);
975
976 req.add(o.primary_plane, {
977 { "FB_ID", fb->id() },
978 });
979 }
980
981 for (const PlaneInfo& p : o.planes) { 963 for (const PlaneInfo& p : o.planes) {
982 auto fb = p.fbs[cur]; 964 auto fb = p.fbs[cur];
983 965
@@ -993,8 +975,8 @@ private:
993 { 975 {
994 unsigned cur = frame_num % s_num_buffers; 976 unsigned cur = frame_num % s_num_buffers;
995 977
996 if (!o.fbs.empty()) { 978 if (!o.legacy_fbs.empty()) {
997 auto fb = o.fbs[cur]; 979 auto fb = o.legacy_fbs[cur];
998 980
999 draw_bar(fb, frame_num); 981 draw_bar(fb, frame_num);
1000 982
@@ -1110,18 +1092,6 @@ int main(int argc, char **argv)
1110 1092
1111 vector<OutputInfo> outputs = setups_to_outputs(card, resman, output_args); 1093 vector<OutputInfo> outputs = setups_to_outputs(card, resman, output_args);
1112 1094
1113 if (card.has_atomic()) {
1114 for (OutputInfo& o : outputs) {
1115 if (o.fbs.empty())
1116 continue;
1117
1118 o.primary_plane = resman.reserve_primary_plane(o.crtc, o.fbs[0]->format());
1119
1120 if (!o.primary_plane)
1121 EXIT("Could not get primary plane for crtc '%u'", o.crtc->id());
1122 }
1123 }
1124
1125 if (!s_flip_mode) 1095 if (!s_flip_mode)
1126 draw_test_patterns(outputs); 1096 draw_test_patterns(outputs);
1127 1097