diff options
| -rw-r--r-- | utils/kmstest.cpp | 224 | 
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;  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 = ¤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<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);  | 
