| Index: ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
|
| diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
|
| index 6604e83dd58f2ab3d0f6f75bc00c5f94ca07cec4..9a0e03b6ef1054505166e1b5c03900eab072c966 100644
|
| --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
|
| +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
|
| @@ -106,6 +106,13 @@ DrmOverlayValidator::OverlayHints::OverlayHints(uint32_t format,
|
|
|
| DrmOverlayValidator::OverlayHints::~OverlayHints() {}
|
|
|
| +DrmOverlayValidator::OverlayBuffer::OverlayBuffer(
|
| + const scoped_refptr<ScanoutBuffer>& buffer,
|
| + bool is_in_use)
|
| + : buffer(buffer), is_in_use(is_in_use) {}
|
| +
|
| +DrmOverlayValidator::OverlayBuffer::~OverlayBuffer() {}
|
| +
|
| DrmOverlayValidator::DrmOverlayValidator(DrmWindow* window)
|
| : window_(window), overlay_hints_cache_(kMaxCacheSize) {}
|
|
|
| @@ -168,34 +175,80 @@ std::vector<OverlayCheck_Params> DrmOverlayValidator::TestPageFlip(
|
| return validated_params;
|
| }
|
|
|
| -uint32_t DrmOverlayValidator::GetOptimalBufferFormat(
|
| - const OverlayPlane& plane,
|
| - const OverlayPlaneList& plane_list) const {
|
| - const auto& iter = overlay_hints_cache_.Peek(plane_list);
|
| - // We dont have any information in cache about this combination of layers,
|
| - // return standard BGRX format.
|
| - if (iter == overlay_hints_cache_.end())
|
| - return DRM_FORMAT_XRGB8888;
|
| -
|
| - DCHECK(plane_list.size() == iter->second.size());
|
| -
|
| - size_t size = plane_list.size();
|
| - uint32_t index;
|
| - for (index = 0; index < size; index++) {
|
| - const OverlayPlane& test_plane = plane_list.at(index);
|
| - if (test_plane.z_order == plane.z_order &&
|
| - test_plane.plane_transform == plane.plane_transform &&
|
| - test_plane.display_bounds == plane.display_bounds &&
|
| - test_plane.crop_rect == plane.crop_rect) {
|
| - break;
|
| +OverlayPlaneList DrmOverlayValidator::ValidatePlanesForPageFlip(
|
| + const OverlayPlaneList& planes,
|
| + ScanoutBufferGenerator* buffer_generator) {
|
| + // Release any OverlayBuffer which is not in use and mark any in use as
|
| + // available.
|
| + if (!overlay_buffers_cache_.empty()) {
|
| + std::vector<OverlayBuffer> re_usable_buffers;
|
| + for (const auto& processing_buffer : overlay_buffers_cache_) {
|
| + if (processing_buffer.is_in_use) {
|
| + re_usable_buffers.push_back(processing_buffer);
|
| + re_usable_buffers.back().is_in_use = false;
|
| + }
|
| }
|
| +
|
| + overlay_buffers_cache_.swap(re_usable_buffers);
|
| }
|
|
|
| - return iter->second.at(index).optimal_format;
|
| + if (planes.size() <= 1)
|
| + return planes;
|
| +
|
| + HardwareDisplayController* controller = window_->GetController();
|
| + if (!controller)
|
| + return planes;
|
| +
|
| + OverlayPlaneList pending_planes = planes;
|
| + std::sort(pending_planes.begin(), pending_planes.end(),
|
| + [](const OverlayPlane& l, const OverlayPlane& r) {
|
| + return l.z_order < r.z_order;
|
| + });
|
| +
|
| + const auto& iter = overlay_hints_cache_.Get(planes);
|
| + scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
|
| +
|
| + size_t size = planes.size();
|
| + bool use_hints = iter != overlay_hints_cache_.end();
|
| +
|
| + for (size_t i = 0; i < size; i++) {
|
| + auto& plane = pending_planes.at(i);
|
| + if (plane.processing_callback.is_null())
|
| + continue;
|
| +
|
| + uint32_t original_format = plane.buffer->GetFramebufferPixelFormat();
|
| + uint32_t target_format = original_format;
|
| +
|
| + const gfx::Size& original_size = plane.buffer->GetSize();
|
| + gfx::Size target_size =
|
| + GetScaledSize(original_size, plane.display_bounds, plane.crop_rect);
|
| +
|
| + if (use_hints) {
|
| + DCHECK(size == iter->second.size());
|
| + const OverlayHints& hints = iter->second.at(i);
|
| + target_format = hints.optimal_format;
|
| +
|
| + // We can handle plane scaling, avoid scaling buffer here.
|
| + if (!hints.handle_scaling)
|
| + target_size = original_size;
|
| + }
|
| +
|
| + if (original_size != target_size || original_format != target_format) {
|
| + scoped_refptr<ScanoutBuffer> buffer = GetBufferForPageFlip(
|
| + drm, buffer_generator, target_size, target_format);
|
| + DCHECK(buffer);
|
| +
|
| + if (plane.processing_callback.Run(plane.buffer, buffer))
|
| + plane.buffer = buffer;
|
| + }
|
| + }
|
| +
|
| + return pending_planes;
|
| }
|
|
|
| void DrmOverlayValidator::ClearCache() {
|
| overlay_hints_cache_.Clear();
|
| + overlay_buffers_cache_.clear();
|
| }
|
|
|
| void DrmOverlayValidator::UpdateOverlayHintsCache(
|
| @@ -254,4 +307,29 @@ void DrmOverlayValidator::UpdateOverlayHintsCache(
|
| overlay_hints_cache_.Put(preferred_format_test_list, overlay_hints);
|
| }
|
|
|
| +scoped_refptr<ScanoutBuffer> DrmOverlayValidator::GetBufferForPageFlip(
|
| + const scoped_refptr<DrmDevice>& drm_device,
|
| + ScanoutBufferGenerator* buffer_generator,
|
| + const gfx::Size& size,
|
| + uint32_t format) {
|
| + // Check if we can re-use existing buffers.
|
| + for (auto& reusable_buffer : overlay_buffers_cache_) {
|
| + if (reusable_buffer.buffer->GetFramebufferPixelFormat() == format &&
|
| + reusable_buffer.buffer->GetSize() == size &&
|
| + !reusable_buffer.is_in_use) {
|
| + reusable_buffer.is_in_use = true;
|
| + return reusable_buffer.buffer;
|
| + }
|
| + }
|
| +
|
| + gfx::BufferFormat buffer_format = GetBufferFormatFromFourCCFormat(format);
|
| + scoped_refptr<ScanoutBuffer> scanout_buffer =
|
| + buffer_generator->Create(drm_device, buffer_format, size);
|
| +
|
| + overlay_buffers_cache_.push_back(
|
| + OverlayBuffer(scanout_buffer, true /* is_in_use */));
|
| +
|
| + return scanout_buffer;
|
| +}
|
| +
|
| } // namespace ui
|
|
|