Commit 9913c81a authored by Mark Yacoub's avatar Mark Yacoub Committed by Commit Bot

Ensure Modeset buffer uses preferred modifiers.

When creating a plane for modeset, ensure that the plane buffer modifier matches
the modifier we will use in the next page flip, which is created
through the list of preferred modifiers.
Also, pass the preferred modifiers list to GetModesetBuffer() so it could be manipulated for modeset tests.

BUG=979736
TEST=The modifier of the buffer used in Modeset matches the consequent page flip.

Change-Id: I59d5c499961b093f06c19e513a96f49dde471c4a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2463363Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Commit-Queue: Daniele Castagna <dcastagna@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816591}
parent 99e71989
......@@ -93,6 +93,13 @@ CrtcController* GetCrtcController(HardwareDisplayController* controller,
return nullptr;
}
std::vector<uint64_t> GetModifiersForPrimaryFormat(
HardwareDisplayController* controller) {
gfx::BufferFormat format = display::DisplaySnapshot::PrimaryFormat();
uint32_t fourcc_format = ui::GetFourCCFormatForOpaqueFramebuffer(format);
return controller->GetFormatModifiersForModesetting(fourcc_format);
}
} // namespace
ScreenManager::ScreenManager() = default;
......@@ -425,40 +432,34 @@ void ScreenManager::UpdateControllerToWindowMapping() {
DrmOverlayPlane ScreenManager::GetModesetBuffer(
HardwareDisplayController* controller,
const gfx::Rect& bounds) {
DrmWindow* window = FindWindowAt(bounds);
const gfx::Rect& bounds,
const std::vector<uint64_t>& modifiers) {
scoped_refptr<DrmDevice> drm = controller->GetDrmDevice();
uint32_t fourcc_format = ui::GetFourCCFormatForOpaqueFramebuffer(
display::DisplaySnapshot::PrimaryFormat());
// Get the buffer that best reflects what the next Page Flip will look like,
// which is using the preferred modifiers from the controllers.
std::unique_ptr<GbmBuffer> buffer =
drm->gbm_device()->CreateBufferWithModifiers(
fourcc_format, bounds.size(), GBM_BO_USE_SCANOUT, modifiers);
if (!buffer) {
LOG(ERROR) << "Failed to create scanout buffer";
return DrmOverlayPlane::Error();
}
gfx::BufferFormat format = display::DisplaySnapshot::PrimaryFormat();
uint32_t fourcc_format = ui::GetFourCCFormatForOpaqueFramebuffer(format);
const auto& modifiers =
controller->GetFormatModifiersForModesetting(fourcc_format);
// If the current primary plane matches what we need for the next page flip,
// we can clone it.
DrmWindow* window = FindWindowAt(bounds);
if (window) {
const DrmOverlayPlane* primary = window->GetLastModesetBuffer();
const DrmDevice* drm = controller->GetDrmDevice().get();
if (primary && primary->buffer->size() == bounds.size() &&
primary->buffer->drm_device() == drm) {
// If the controller doesn't advertise modifiers, wont have a
// modifier either and we can reuse the buffer. Otherwise, check
// to see if the controller supports the buffers format
// modifier.
if (modifiers.empty())
if (primary->buffer->format_modifier() == buffer->GetFormatModifier())
return primary->Clone();
for (const uint64_t modifier : modifiers) {
if (modifier == primary->buffer->format_modifier())
return primary->Clone();
}
}
}
scoped_refptr<DrmDevice> drm = controller->GetDrmDevice();
std::unique_ptr<GbmBuffer> buffer =
drm->gbm_device()->CreateBufferWithModifiers(
fourcc_format, bounds.size(), GBM_BO_USE_SCANOUT, modifiers);
if (!buffer) {
LOG(ERROR) << "Failed to create scanout buffer";
return DrmOverlayPlane::Error();
}
scoped_refptr<DrmFramebuffer> framebuffer = DrmFramebuffer::AddFramebuffer(
drm, buffer.get(), buffer->GetSize(), modifiers);
if (!framebuffer) {
......@@ -481,7 +482,9 @@ DrmOverlayPlane ScreenManager::GetModesetBuffer(
bool ScreenManager::EnableController(HardwareDisplayController* controller) {
DCHECK(!controller->crtc_controllers().empty());
gfx::Rect rect(controller->origin(), controller->GetModeSize());
DrmOverlayPlane plane = GetModesetBuffer(controller, rect);
auto modifiers = GetModifiersForPrimaryFormat(controller);
DrmOverlayPlane plane = GetModesetBuffer(controller, rect, modifiers);
if (!plane.buffer || !controller->Enable(plane)) {
LOG(ERROR) << "Failed to enable controller";
return false;
......@@ -497,7 +500,8 @@ bool ScreenManager::ModesetController(HardwareDisplayController* controller,
gfx::Rect rect(origin, gfx::Size(mode.hdisplay, mode.vdisplay));
controller->set_origin(origin);
DrmOverlayPlane plane = GetModesetBuffer(controller, rect);
auto modifiers = GetModifiersForPrimaryFormat(controller);
DrmOverlayPlane plane = GetModesetBuffer(controller, rect, modifiers);
if (!plane.buffer || !controller->Modeset(plane, mode)) {
LOG(ERROR) << "Failed to modeset controller";
return false;
......
......@@ -138,7 +138,8 @@ class ScreenManager {
const drmModeModeInfo& mode);
DrmOverlayPlane GetModesetBuffer(HardwareDisplayController* controller,
const gfx::Rect& bounds);
const gfx::Rect& bounds,
const std::vector<uint64_t>& modifiers);
bool EnableController(HardwareDisplayController* controller);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment