Skip to content

Commit cff33ca

Browse files
authored
Enhancements to initialization code in drm backend (#344)
* Check if drm_crtc is nullptr before attempting to set mode In native_window_drm, there's no check against null drm_crtc. So if drm_crtc is null, and SwapBuffers() is called, a Segmentation Fault will occur. This adds check against it. Signed-off-by: Yunhao Tian <[email protected]> * Add logic to initialize drm encoder and crtc In RK3399 board, when the system just booted up, there's no encoder attached to connector, and no crtc attached to encoder. In this case drm backend will fail to get an encoder. This commit adds code to find suitable encoder and crtc from resources, when absent. Signed-off-by: Yunhao Tian <[email protected]> * Add myself to AUTHORS --------- Signed-off-by: Yunhao Tian <[email protected]>
1 parent 048334d commit cff33ca

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ Andrea Daoud ([email protected])
1010
Valentin Hăloiu ([email protected])
1111
1212
Makoto Sato ([email protected])
13+
Yunhao Tian ([email protected])

src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,18 @@ bool NativeWindowDrm::ConfigureDisplay(const uint16_t rotation) {
7777
drmModeFreeResources(resources);
7878
return false;
7979
}
80-
if (encoder->crtc_id) {
81-
drm_crtc_ = drmModeGetCrtc(drm_device_, encoder->crtc_id);
80+
if (!encoder->crtc_id) {
81+
// if there is no current CRTC, make sure to attach a suitable one
82+
for (int c = 0; c < resources->count_crtcs; c++) {
83+
if (encoder->possible_crtcs & (1 << c)) {
84+
encoder->crtc_id = resources->crtcs[c];
85+
break;
86+
}
87+
}
88+
}
89+
drm_crtc_ = drmModeGetCrtc(drm_device_, encoder->crtc_id);
90+
if (!drm_crtc_) {
91+
ELINUX_LOG(WARNING) << "Couldn't find a suitable crtc";
8292
}
8393

8494
drmModeFreeEncoder(encoder);
@@ -103,11 +113,44 @@ drmModeConnectorPtr NativeWindowDrm::FindConnector(drmModeResPtr resources) {
103113

104114
drmModeEncoder* NativeWindowDrm::FindEncoder(drmModeRes* resources,
105115
drmModeConnector* connector) {
106-
if (connector->encoder_id) {
107-
return drmModeGetEncoder(drm_device_, connector->encoder_id);
116+
drmModeEncoder* encoder = nullptr;
117+
// Find a suitable encoder
118+
for (int e = 0; e < resources->count_encoders; e++) {
119+
bool found = false;
120+
encoder = drmModeGetEncoder(drm_device_, resources->encoders[e]);
121+
for (int ce = 0; ce < connector->count_encoders; ce++) {
122+
if (encoder && encoder->encoder_id == connector->encoders[ce]) {
123+
ELINUX_LOG(DEBUG) << "Using encoder id " << encoder->encoder_id;
124+
found = true;
125+
break;
126+
}
127+
}
128+
if (found)
129+
break;
130+
drmModeFreeEncoder(encoder);
131+
encoder = nullptr;
108132
}
109-
// no encoder found
110-
return nullptr;
133+
134+
// If encoder is not connected to the connector,
135+
// try to find a suitable one
136+
if (!encoder) {
137+
for (int e = 0; e < connector->count_encoders; e++) {
138+
encoder = drmModeGetEncoder(drm_device_, connector->encoders[e]);
139+
for (int c = 0; c < resources->count_crtcs; c++) {
140+
if (encoder->possible_crtcs & (1 << c)) {
141+
encoder->crtc_id = resources->crtcs[c];
142+
break;
143+
}
144+
}
145+
if (encoder->crtc_id)
146+
break;
147+
drmModeFreeEncoder(encoder);
148+
encoder = nullptr;
149+
}
150+
}
151+
152+
// Will return nullptr if a suitable encoder is still not found
153+
return encoder;
111154
}
112155

113156
const uint32_t* NativeWindowDrm::GetCursorData(const std::string& cursor_name) {

src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,14 @@ void NativeWindowDrmGbm::SwapBuffers() {
175175
if (result != 0) {
176176
ELINUX_LOG(ERROR) << "Failed to add a framebuffer. (" << result << ")";
177177
}
178-
result = drmModeSetCrtc(drm_device_, drm_crtc_->crtc_id, fb, 0, 0,
179-
&drm_connector_id_, 1, &drm_mode_info_);
180-
if (result != 0) {
181-
ELINUX_LOG(ERROR) << "Failed to set crct mode. (" << result << ")";
178+
if (!drm_crtc_) {
179+
ELINUX_LOG(ERROR) << "crtc is null, cannot set mode.";
180+
} else {
181+
result = drmModeSetCrtc(drm_device_, drm_crtc_->crtc_id, fb, 0, 0,
182+
&drm_connector_id_, 1, &drm_mode_info_);
183+
if (result != 0) {
184+
ELINUX_LOG(ERROR) << "Failed to set crct mode. (" << result << ")";
185+
}
182186
}
183187

184188
if (gbm_previous_bo_) {

0 commit comments

Comments
 (0)