diff --git a/common/compositor/gl/egloffscreencontext.cpp b/common/compositor/gl/egloffscreencontext.cpp index 5bbd6e1c..f46c5f99 100644 --- a/common/compositor/gl/egloffscreencontext.cpp +++ b/common/compositor/gl/egloffscreencontext.cpp @@ -87,23 +87,27 @@ bool EGLOffScreenContext::MakeCurrent() { return true; } -EGLint EGLOffScreenContext::GetSyncFD() { +EGLint EGLOffScreenContext::GetSyncFD(bool onScreen) { EGLint sync_fd = -1; - EGLSyncKHR egl_sync = - eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); - if (egl_sync == EGL_NO_SYNC_KHR) { - ETRACE("Failed to make sync object."); - return -1; - } + if (onScreen) + glFlush(); + else { + EGLSyncKHR egl_sync = + eglCreateSyncKHR(egl_display_, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); + if (egl_sync == EGL_NO_SYNC_KHR) { + ETRACE("Failed to make sync object."); + return -1; + } - sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync); - if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { - ETRACE("Failed to duplicate native fence object."); - sync_fd = -1; - } + sync_fd = eglDupNativeFenceFDANDROID(egl_display_, egl_sync); + if (sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { + ETRACE("Failed to duplicate native fence object."); + sync_fd = -1; + } - eglDestroySyncKHR(egl_display_, egl_sync); + eglDestroySyncKHR(egl_display_, egl_sync); + } return sync_fd; } diff --git a/common/compositor/gl/egloffscreencontext.h b/common/compositor/gl/egloffscreencontext.h index 464a3214..7ad1d3ce 100644 --- a/common/compositor/gl/egloffscreencontext.h +++ b/common/compositor/gl/egloffscreencontext.h @@ -28,7 +28,7 @@ class EGLOffScreenContext { bool Init(); - EGLint GetSyncFD(); + EGLint GetSyncFD(bool onScreen); EGLDisplay GetDisplay() const { return egl_display_; diff --git a/common/compositor/gl/glrenderer.cpp b/common/compositor/gl/glrenderer.cpp index 7ada3d04..dd4c3f69 100644 --- a/common/compositor/gl/glrenderer.cpp +++ b/common/compositor/gl/glrenderer.cpp @@ -64,9 +64,11 @@ bool GLRenderer::Init() { glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); - std::unique_ptr program(new GLProgram()); - if (program->Init(1)) { - programs_.emplace_back(std::move(program)); + for (int i = 1; i < 5; i++) { + std::unique_ptr program(new GLProgram()); + if (program->Init(i)) { + programs_.emplace_back(std::move(program)); + } } glEnableVertexAttribArray(0); @@ -173,7 +175,7 @@ bool GLRenderer::Draw(const std::vector &render_states, glDisable(GL_SCISSOR_TEST); if (!disable_explicit_sync_) - surface->SetNativeFence(context_.GetSyncFD()); + surface->SetNativeFence(context_.GetSyncFD(surface->IsOnScreen())); surface->ResetDamage(); #ifdef COMPOSITOR_TRACING diff --git a/common/core/gpudevice.cpp b/common/core/gpudevice.cpp index d125b6ac..0505b090 100644 --- a/common/core/gpudevice.cpp +++ b/common/core/gpudevice.cpp @@ -130,6 +130,15 @@ bool GpuDevice::EnableDRMCommit(bool enable, uint32_t display_id) { return ret; } +void GpuDevice::MarkDisplayForFirstCommit() { + size_t size = total_displays_.size(); + for (size_t i = 0; i < size; i++) { + if (total_displays_.at(i)->IsConnected()) { + total_displays_.at(i)->MarkFirstCommit(); + } + } +} + bool GpuDevice::ResetDrmMaster(bool drop_master) { bool ret = true; if (drop_master) { @@ -149,6 +158,7 @@ bool GpuDevice::ResetDrmMaster(bool drop_master) { // In case of setDrmMaster or the lock file is not exist. // Re-set DRM Master true. display_manager_->setDrmMaster(false); + MarkDisplayForFirstCommit(); ResetAllDisplayCommit(true); DisableWatch(); @@ -390,6 +400,8 @@ void GpuDevice::ParseLogicalDisplaySetting( logical_split_str.find_first_not_of("0123456789") != std::string::npos) return; uint32_t physical_index = atoi(physical_index_str.c_str()); + if (physical_index < 0) + return; uint32_t logical_split_num = atoi(logical_split_str.c_str()); if (logical_split_num <= 1) return; diff --git a/common/core/hwclayer.cpp b/common/core/hwclayer.cpp index c2771935..1d7c26d4 100644 --- a/common/core/hwclayer.cpp +++ b/common/core/hwclayer.cpp @@ -106,21 +106,20 @@ void HwcLayer::SetDisplayFrame(const HwcRect& display_frame, void HwcLayer::SetSurfaceDamage(const HwcRegion& surface_damage) { uint32_t rects = surface_damage.size(); state_ |= kLayerContentChanged; + state_ |= kSurfaceDamageChanged; HwcRect rect; ResetRectToRegion(surface_damage, rect); if (rects == 1) { if ((rect.top == 0) && (rect.bottom == 0) && (rect.left == 0) && (rect.right == 0)) { state_ &= ~kLayerContentChanged; - state_ &= ~kSurfaceDamageChanged; UpdateRenderingDamage(rect, rect, true); surface_damage_.reset(); return; - } else { - state_ |= kSurfaceDamageChanged; } } else if (rects == 0) { rect = display_frame_; + // damage is assigned with display_frame, no need to transform state_ &= ~kSurfaceDamageChanged; } @@ -265,51 +264,12 @@ void HwcLayer::SufaceDamageTransfrom() { translated_damage.top = translated_damage.top * ratioh + 0.5; translated_damage.bottom = translated_damage.bottom * ratioh + 0.5; - if (transform_ == hwcomposer::HWCTransform::kTransform270) { - ox = display_frame_.left; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox + translated_damage.top; - current_rendering_damage_.top = oy - translated_damage.right; - current_rendering_damage_.right = ox + translated_damage.bottom; - current_rendering_damage_.bottom = oy - translated_damage.left; - } else if (transform_ == hwcomposer::HWCTransform::kTransform180) { - ox = display_frame_.right; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox - translated_damage.right; - current_rendering_damage_.top = oy - translated_damage.bottom; - current_rendering_damage_.right = ox - translated_damage.left; - current_rendering_damage_.bottom = oy - translated_damage.top; - } else if (transform_ & hwcomposer::HWCTransform::kTransform90) { - if (transform_ & hwcomposer::HWCTransform::kReflectX) { - ox = display_frame_.left; - oy = display_frame_.top; - current_rendering_damage_.left = ox + translated_damage.top; - current_rendering_damage_.top = oy + translated_damage.left; - current_rendering_damage_.right = ox + translated_damage.bottom; - current_rendering_damage_.bottom = oy + translated_damage.right; - } else if (transform_ & hwcomposer::HWCTransform::kReflectY) { - ox = display_frame_.right; - oy = display_frame_.bottom; - current_rendering_damage_.left = ox - translated_damage.bottom; - current_rendering_damage_.top = oy - translated_damage.right; - current_rendering_damage_.right = ox - translated_damage.top; - current_rendering_damage_.bottom = oy - translated_damage.left; - } else { - ox = display_frame_.right; - oy = display_frame_.top; - current_rendering_damage_.left = ox - translated_damage.bottom; - current_rendering_damage_.top = oy + translated_damage.left; - current_rendering_damage_.right = ox - translated_damage.top; - current_rendering_damage_.bottom = oy + translated_damage.right; - } - } else if (transform_ == 0) { - ox = display_frame_.left; - oy = display_frame_.top; - current_rendering_damage_.left = ox + translated_damage.left; - current_rendering_damage_.top = oy + translated_damage.top; - current_rendering_damage_.right = ox + translated_damage.right; - current_rendering_damage_.bottom = oy + translated_damage.bottom; - } + ox = display_frame_.left; + oy = display_frame_.top; + current_rendering_damage_.left = ox + translated_damage.left; + current_rendering_damage_.top = oy + translated_damage.top; + current_rendering_damage_.right = ox + translated_damage.right; + current_rendering_damage_.bottom = oy + translated_damage.bottom; #ifdef RECT_DAMAGE_TRACING IRECTDAMAGETRACE( "Re-calucated current_rendering_damage_ (LTWH): %d, %d, %d, %d", @@ -317,6 +277,8 @@ void HwcLayer::SufaceDamageTransfrom() { (current_rendering_damage_.right - current_rendering_damage_.left), (current_rendering_damage_.bottom - current_rendering_damage_.top)); #endif + } else { + current_rendering_damage_ = translated_damage; } } diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index 87f6276d..0946b73d 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -138,8 +138,8 @@ void OverlayLayer::SetDisplayFrame(const HwcRect& display_frame) { } void OverlayLayer::SetTransform(uint32_t transform) { - plane_transform_ = transform; transform_ = transform; + merged_transform_ = transform; } void OverlayLayer::ValidateTransform(uint32_t transform, @@ -173,29 +173,112 @@ void OverlayLayer::ValidateTransform(uint32_t transform, // The elements {0, 1, 2, 3} form a circulant matrix under mod 4 arithmetic mtransform = (mtransform + mdisplay_transform) % 4; mtransform = inv_tmap[mtransform]; - plane_transform_ = mtransform; + merged_transform_ = mtransform; - if (plane_transform_ & kTransform90) { + if (merged_transform_ & kTransform90) { if (transform & kReflectX) - plane_transform_ |= kReflectX; + merged_transform_ |= kReflectX; if (transform & kReflectY) - plane_transform_ |= kReflectY; + merged_transform_ |= kReflectY; } } +void OverlayLayer::TransformDamage(HwcLayer* layer, uint32_t max_height, + uint32_t max_width) { + const HwcRect& surface_damage = layer->GetLayerDamage(); + if (surface_damage.empty() || !layer->HasSurfaceDamageRegionChanged()) { + surface_damage_ = surface_damage; + return; + } + HwcRect translated_damage = TranslateRect(surface_damage, 0, 0); +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Calculating Overlaylayer Damage for layer[%d]", z_order_); + IRECTDAMAGETRACE("max_width: %d, max_height:%d", max_width, max_height); + IRECTDAMAGETRACE("Original Surface_damage (LTWH): %d, %d, %d, %d", + surface_damage.left, surface_damage.top, + (surface_damage.right - surface_damage.left), + (surface_damage.bottom - surface_damage.top)); + IRECTDAMAGETRACE("translated_damage (LTWH): %d, %d, %d, %d", + translated_damage.left, translated_damage.top, + (translated_damage.right - translated_damage.left), + (translated_damage.bottom - translated_damage.top)); + IRECTDAMAGETRACE("source_crop_ (LTWH): %f, %f, %f, %f", source_crop_.left, + source_crop_.top, (source_crop_.right - source_crop_.left), + (source_crop_.bottom - source_crop_.top)); + IRECTDAMAGETRACE("display_frame_ (LTWH): %d, %d, %d, %d", display_frame_.left, + display_frame_.top, + (display_frame_.right - display_frame_.left), + (display_frame_.bottom - display_frame_.top)); +#endif + float ratio_w_h = max_width * 1.0 / max_height; + float ratio_h_w = max_height * 1.0 / max_width; + + int ox = 0, oy = 0; + + if (merged_transform_ == kTransform270) { + oy = max_height; + surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; + surface_damage_.top = oy - translated_damage.right * ratio_h_w + 0.5; + surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.bottom = oy - translated_damage.left * ratio_h_w + 0.5; + } else if (merged_transform_ == kTransform180) { + ox = max_width; + oy = max_height; + surface_damage_.left = ox - translated_damage.right; + surface_damage_.top = oy - translated_damage.bottom; + surface_damage_.right = ox - translated_damage.left; + surface_damage_.bottom = oy - translated_damage.top; + } else if (merged_transform_ & hwcomposer::HWCTransform::kTransform90) { + if (merged_transform_ & kReflectX) { + surface_damage_.left = translated_damage.top * ratio_w_h + 0.5; + surface_damage_.top = translated_damage.left * ratio_h_w + 0.5; + surface_damage_.right = translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; + } else if (merged_transform_ & kReflectY) { + ox = max_width; + oy = max_height; + surface_damage_.left = ox - (translated_damage.bottom * ratio_w_h + 0.5); + surface_damage_.top = oy - (translated_damage.right * ratio_h_w + 0.5); + surface_damage_.right = ox - (translated_damage.top * ratio_w_h + 0.5); + surface_damage_.bottom = oy - (translated_damage.left * ratio_h_w + 0.5); + } else { + ox = max_width; + surface_damage_.left = ox - translated_damage.bottom * ratio_w_h + 0.5; + surface_damage_.top = translated_damage.left * ratio_h_w + 0.5; + surface_damage_.right = ox - translated_damage.top * ratio_w_h + 0.5; + surface_damage_.bottom = translated_damage.right * ratio_h_w + 0.5; + } + } else if (merged_transform_ == 0) { + surface_damage_.left = translated_damage.left; + surface_damage_.top = translated_damage.top; + surface_damage_.right = translated_damage.right; + surface_damage_.bottom = translated_damage.bottom; + } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Surface_damage (LTWH): %d, %d, %d, %d", + surface_damage_.left, surface_damage_.top, + (surface_damage_.right - surface_damage_.left), + (surface_damage_.bottom - surface_damage_.top)); +#endif +} + void OverlayLayer::InitializeState(HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, uint32_t rotation, - bool handle_constraints) { + uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints) { transform_ = layer->GetTransform(); + plane_transform_ = rotation; if (rotation != kRotateNone) { ValidateTransform(layer->GetTransform(), rotation); } else { - plane_transform_ = transform_; + merged_transform_ = transform_; } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("validated plane_transform_: %d", plane_transform_); +#endif alpha_ = layer->GetAlpha(); layer_index_ = layer_index; @@ -205,9 +288,8 @@ void OverlayLayer::InitializeState(HwcLayer* layer, source_crop_ = layer->GetSourceCrop(); dataspace_ = layer->GetDataSpace(); blending_ = layer->GetBlending(); - surface_damage_ = layer->GetLayerDamage(); - solid_color_ = layer->GetSolidColor(); + TransformDamage(layer, max_height, max_width); if (previous_layer && layer->HasZorderChanged()) { if (previous_layer->actual_composition_ == kGpu) { @@ -257,6 +339,12 @@ void OverlayLayer::InitializeState(HwcLayer* layer, if (previous_layer) { ValidatePreviousFrameState(previous_layer, layer); } +#ifdef RECT_DAMAGE_TRACING + IRECTDAMAGETRACE("Surface_damage after init (LTWH): %d, %d, %d, %d", + surface_damage_.left, surface_damage_.top, + (surface_damage_.right - surface_damage_.left), + (surface_damage_.bottom - surface_damage_.top)); +#endif return; } @@ -376,22 +464,23 @@ void OverlayLayer::InitializeState(HwcLayer* layer, void OverlayLayer::InitializeFromHwcLayer( HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, uint32_t rotation, bool handle_constraints) { + uint32_t max_height, uint32_t max_width, uint32_t rotation, + bool handle_constraints) { display_frame_width_ = layer->GetDisplayFrameWidth(); display_frame_height_ = layer->GetDisplayFrameHeight(); display_frame_ = layer->GetDisplayFrame(); InitializeState(layer, resource_manager, previous_layer, z_order, layer_index, - max_height, rotation, handle_constraints); + max_height, max_width, rotation, handle_constraints); } void OverlayLayer::InitializeFromScaledHwcLayer( HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - const HwcRect& display_frame, uint32_t max_height, uint32_t rotation, - bool handle_constraints) { + const HwcRect& display_frame, uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints) { SetDisplayFrame(display_frame); InitializeState(layer, resource_manager, previous_layer, z_order, layer_index, - max_height, rotation, handle_constraints); + max_height, max_width, rotation, handle_constraints); } void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, @@ -482,7 +571,7 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, if (!layer->HasVisibleRegionChanged() && !content_changed && surface_damage_.empty() && !layer->HasLayerContentChanged() && - !(state_ & kNeedsReValidation)) { + !(state_ & kNeedsReValidation) && !force_content_changed_) { state_ &= ~kLayerContentChanged; } } @@ -512,6 +601,7 @@ void OverlayLayer::CloneLayer(const OverlayLayer* layer, surface_damage_ = layer->GetSurfaceDamage(); transform_ = layer->transform_; plane_transform_ = layer->plane_transform_; + merged_transform_ = layer->merged_transform_; alpha_ = layer->alpha_; layer_index_ = z_order; z_order_ = z_order; diff --git a/common/core/overlaylayer.h b/common/core/overlaylayer.h index 40b62580..22d4930b 100644 --- a/common/core/overlaylayer.h +++ b/common/core/overlaylayer.h @@ -49,15 +49,16 @@ struct OverlayLayer { void InitializeFromHwcLayer(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, uint32_t max_height, - uint32_t rotation, bool handle_constraints); + uint32_t max_width, uint32_t rotation, + bool handle_constraints); void InitializeFromScaledHwcLayer(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, const HwcRect& display_frame, - uint32_t max_height, uint32_t rotation, - bool handle_constraints); + uint32_t max_height, uint32_t max_width, + uint32_t rotation, bool handle_constraints); // Get z order of this layer. uint32_t GetZorder() const { return z_order_; @@ -87,12 +88,18 @@ struct OverlayLayer { return transform_; } + // This represents hwc transform setting for this + // display on which this layer is being shown. + uint32_t GetPlaneTransform() const { + return plane_transform_; + } + // This represents any transform applied // to this layer(i.e. GetTransform()) + overall // rotation applied to the display on which this // layer is being shown. - uint32_t GetPlaneTransform() const { - return plane_transform_; + uint32_t GetMergedTransform() const { + return merged_transform_; } // Applies transform to this layer before scanout. @@ -116,11 +123,17 @@ struct OverlayLayer { } const HwcRect& GetSurfaceDamage() const { - return surface_damage_; + if (force_content_changed_) + return display_frame_; + else + return surface_damage_; } HwcRect& GetSurfaceDamage() { - return surface_damage_; + if (force_content_changed_) + return display_frame_; + else + return surface_damage_; } uint32_t GetSourceCropWidth() const { @@ -245,6 +258,10 @@ struct OverlayLayer { void CloneLayer(const OverlayLayer* layer, const HwcRect& display_frame, ResourceManager* resource_manager, uint32_t z_order); + void SetForceContentChanged() { + force_content_changed_ = true; + } + void Dump(); private: @@ -277,13 +294,18 @@ struct OverlayLayer { void ValidateTransform(uint32_t transform, uint32_t display_transform); + void TransformDamage(HwcLayer* layer, uint32_t max_height, + uint32_t max_width); + void InitializeState(HwcLayer* layer, ResourceManager* buffer_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, uint32_t max_height, - uint32_t rotation, bool handle_constraints); + uint32_t max_width, uint32_t rotation, + bool handle_constraints); uint32_t transform_ = 0; uint32_t plane_transform_ = 0; + uint32_t merged_transform_ = 0; uint32_t z_order_ = 0; uint32_t layer_index_ = 0; uint32_t source_crop_width_ = 0; @@ -294,6 +316,7 @@ struct OverlayLayer { uint32_t dataspace_ = 0; uint32_t solid_color_ = 0; + bool force_content_changed_ = false; HwcRect source_crop_; HwcRect display_frame_; diff --git a/common/display/displayplanemanager.cpp b/common/display/displayplanemanager.cpp index 5104c66d..2d678e10 100644 --- a/common/display/displayplanemanager.cpp +++ b/common/display/displayplanemanager.cpp @@ -19,6 +19,7 @@ #include "displayplanemanager.h" #include "displayplane.h" +#include "drm/drmplane.h" #include "factory.h" #include "hwctrace.h" #include "nativesurface.h" @@ -67,6 +68,15 @@ bool DisplayPlaneManager::Initialize(uint32_t width, uint32_t height) { return status; } +void DisplayPlaneManager::ResetPlanes(drmModeAtomicReqPtr pset) { + for (auto j = overlay_planes_.begin(); j < overlay_planes_.end(); j++) { + if (!j->get()->InUse()) { + DrmPlane *drmplane = (DrmPlane *)(j->get()); + drmplane->Disable(pset); + } + } +} + bool DisplayPlaneManager::ValidateLayers( std::vector &layers, int add_index, bool disable_overlay, bool *commit_checked, bool *re_validation_needed, diff --git a/common/display/displayplanemanager.h b/common/display/displayplanemanager.h index a25fd2ee..a20144b5 100644 --- a/common/display/displayplanemanager.h +++ b/common/display/displayplanemanager.h @@ -122,6 +122,8 @@ class DisplayPlaneManager { void ReleaseUnreservedPlanes(std::vector &reserved_planes); + void ResetPlanes(drmModeAtomicReqPtr pset); + private: DisplayPlaneState *GetLastUsedOverlay(DisplayPlaneStateList &composition); bool FallbacktoGPU(DisplayPlane *target_plane, OverlayLayer *layer, diff --git a/common/display/displayplanestate.cpp b/common/display/displayplanestate.cpp index 7265f91a..f4392b7e 100644 --- a/common/display/displayplanestate.cpp +++ b/common/display/displayplanestate.cpp @@ -612,7 +612,7 @@ void DisplayPlaneState::ValidateReValidation() { if (private_data_->source_layers_.size() == 1 && !(private_data_->type_ == DisplayPlanePrivateState::PlaneType::kVideo)) { re_validate_layer_ |= ReValidationType::kScanout; - } else { + } else if (!IsVideoPlane()) { bool use_scalar = CanUseDisplayUpScaling(); if (private_data_->use_plane_scalar_ != use_scalar) { re_validate_layer_ |= ReValidationType::kUpScalar; diff --git a/common/display/displayqueue.cpp b/common/display/displayqueue.cpp index 011027eb..322763a4 100644 --- a/common/display/displayqueue.cpp +++ b/common/display/displayqueue.cpp @@ -19,7 +19,7 @@ #include #include #include - +#include #include #include "displayplanemanager.h" @@ -545,6 +545,8 @@ void DisplayQueue::InitializeOverlayLayers( layers.emplace_back(); OverlayLayer* overlay_layer = &(layers.back()); + if (refrsh_display_id_ > 0) + overlay_layer->SetForceContentChanged(); OverlayLayer* previous_layer = NULL; if (previous_size > z_order) { previous_layer = &(in_flight_layers_.at(z_order)); @@ -568,12 +570,14 @@ void DisplayQueue::InitializeOverlayLayers( overlay_layer->InitializeFromScaledHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - display_frame, display_plane_manager_->GetHeight(), plane_transform_, + display_frame, display_plane_manager_->GetHeight(), + display_plane_manager_->GetWidth(), plane_transform_, handle_constraints); } else { overlay_layer->InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - display_plane_manager_->GetHeight(), plane_transform_, + display_plane_manager_->GetHeight(), + display_plane_manager_->GetWidth(), plane_transform_, handle_constraints); } @@ -899,10 +903,11 @@ bool DisplayQueue::QueueUpdate(std::vector& source_layers, int32_t fence = 0; bool fence_released = false; - if (!IsIgnoreUpdates()) + if (!IsIgnoreUpdates()) { composition_passed = display_->Commit( current_composition_planes, previous_plane_state_, disable_explictsync, kms_fence_, &fence, &fence_released); + } if (fence_released) { kms_fence_ = 0; @@ -1248,6 +1253,10 @@ void DisplayQueue::SetCloneMode(bool cloned) { clone_rendered_ = false; } +void DisplayQueue::ResetPlanes(drmModeAtomicReqPtr pset) { + display_plane_manager_->ResetPlanes(pset); +} + void DisplayQueue::IgnoreUpdates() { idle_tracker_.idle_frames_ = 0; idle_tracker_.state_ = FrameStateTracker::kIgnoreUpdates; diff --git a/common/display/displayqueue.h b/common/display/displayqueue.h index cfadabc1..e6aaaae5 100644 --- a/common/display/displayqueue.h +++ b/common/display/displayqueue.h @@ -110,6 +110,8 @@ class DisplayQueue { void IgnoreUpdates(); + void ResetPlanes(drmModeAtomicReqPtr pset); + void PresentClonedCommit(DisplayQueue* queue); const DisplayPlaneStateList& GetCurrentCompositionPlanes() const { diff --git a/common/display/virtualdisplay.cpp b/common/display/virtualdisplay.cpp index be579520..fdd2d341 100644 --- a/common/display/virtualdisplay.cpp +++ b/common/display/virtualdisplay.cpp @@ -349,7 +349,7 @@ bool VirtualDisplay::Present(std::vector &source_layers, overlay_layer.InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - height_, kIdentity, handle_constraints); + height_, width_, kIdentity, handle_constraints); index.emplace_back(z_order); layers_rects.emplace_back(layer->GetDisplayFrame()); z_order++; diff --git a/common/display/virtualpanoramadisplay.cpp b/common/display/virtualpanoramadisplay.cpp index 12d84c61..bfd78a5d 100644 --- a/common/display/virtualpanoramadisplay.cpp +++ b/common/display/virtualpanoramadisplay.cpp @@ -350,7 +350,7 @@ bool VirtualPanoramaDisplay::Present(std::vector &source_layers, overlay_layer.InitializeFromHwcLayer( layer, resource_manager_.get(), previous_layer, z_order, layer_index, - height_, kIdentity, handle_constraints); + height_, width_, kIdentity, handle_constraints); index.emplace_back(z_order); layers_rects.emplace_back(overlay_layer.GetDisplayFrame()); diff --git a/os/android/hwcservice.cpp b/os/android/hwcservice.cpp index b032fb56..f6116ac4 100644 --- a/os/android/hwcservice.cpp +++ b/os/android/hwcservice.cpp @@ -409,6 +409,10 @@ bool HwcService::Controls::EnableDRMCommit(bool enable, uint32_t display_id) { return mHwc.EnableDRMCommit(enable, display_id); } +bool HwcService::Controls::ResetDrmMaster(bool drop_master) { + return mHwc.ResetDrmMaster(drop_master); +} + status_t HwcService::Controls::VideoEnableEncryptedSession( uint32_t sessionID, uint32_t instanceID) { mHwc.SetPAVPSessionStatus(true, sessionID, instanceID); diff --git a/os/android/hwcservice.h b/os/android/hwcservice.h index 481b9a26..bb8ecaf3 100644 --- a/os/android/hwcservice.h +++ b/os/android/hwcservice.h @@ -108,6 +108,7 @@ class HwcService : public BnService { uint32_t SRMLength); uint32_t GetDisplayIDFromConnectorID(uint32_t connector_id); bool EnableDRMCommit(bool enable, uint32_t display_id); + bool ResetDrmMaster(bool drop_master); status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID); status_t VideoDisableAllEncryptedSessions(uint32_t sessionID); diff --git a/os/android/iahwc2.cpp b/os/android/iahwc2.cpp index bae818b1..8c0e0700 100644 --- a/os/android/iahwc2.cpp +++ b/os/android/iahwc2.cpp @@ -949,12 +949,9 @@ HWC2::Error IAHWC2::Hwc2Layer::SetLayerSurfaceDamage(hwc_region_t damage) { hwcomposer::HwcRegion hwc_region; for (size_t rect = 0; rect < num_rects; ++rect) { - if (!(damage.rects[rect].left == 0 && damage.rects[rect].top == 0 && - damage.rects[rect].right == 0 && damage.rects[rect].bottom == 0)) { - hwc_region.emplace_back(damage.rects[rect].left, damage.rects[rect].top, - damage.rects[rect].right, - damage.rects[rect].bottom); - } + hwc_region.emplace_back(damage.rects[rect].left, damage.rects[rect].top, + damage.rects[rect].right, + damage.rects[rect].bottom); } hwc_layer_.SetSurfaceDamage(hwc_region); @@ -1233,6 +1230,7 @@ int IAHWC2::HookDevOpen(const struct hw_module_t *module, const char *name, HWC2::Error err = ctx->Init(); if (err != HWC2::Error::None) { ALOGE("Failed to initialize IAHWC2 err=%d\n", err); + ctx.reset(); return -EINVAL; } @@ -1311,6 +1309,10 @@ bool IAHWC2::EnableDRMCommit(bool enable, uint32_t display_id) { return device_.EnableDRMCommit(enable, display_id); } +bool IAHWC2::ResetDrmMaster(bool drop_master) { + return device_.ResetDrmMaster(drop_master); +} + void IAHWC2::SetHDCPSRMForDisplay(uint32_t connector, const int8_t *SRM, uint32_t SRMLength) { if (SRM == NULL) { diff --git a/os/android/iahwc2.h b/os/android/iahwc2.h index 1062860e..82cea0e1 100644 --- a/os/android/iahwc2.h +++ b/os/android/iahwc2.h @@ -74,6 +74,8 @@ class IAHWC2 : public hwc2_device_t { bool EnableDRMCommit(bool enable, uint32_t display_id); + bool ResetDrmMaster(bool drop_master); + public: class Hwc2Layer { public: diff --git a/os/android/libhwcservice/hwcserviceapi.cpp b/os/android/libhwcservice/hwcserviceapi.cpp index 45960424..7366abb0 100644 --- a/os/android/libhwcservice/hwcserviceapi.cpp +++ b/os/android/libhwcservice/hwcserviceapi.cpp @@ -315,6 +315,15 @@ status_t HwcService_EnableDRMCommit(HWCSHANDLE hwcs, uint32_t enable, return pContext->mControls->EnableDRMCommit(enable, display_id); } +status_t HwcService_ResetDrmMaster(HWCSHANDLE hwcs, uint32_t drop_master) { + HwcsContext* pContext = static_cast(hwcs); + if (!pContext) { + return android::BAD_VALUE; + } + + return pContext->mControls->ResetDrmMaster(drop_master); +} + status_t HwcService_Video_DisableHDCPSession_AllDisplays(HWCSHANDLE hwcs) { HwcsContext* pContext = static_cast(hwcs); if (!pContext) { diff --git a/os/android/libhwcservice/hwcserviceapi.h b/os/android/libhwcservice/hwcserviceapi.h index e0f6e2e9..68c5dd2f 100644 --- a/os/android/libhwcservice/hwcserviceapi.h +++ b/os/android/libhwcservice/hwcserviceapi.h @@ -224,6 +224,8 @@ uint32_t HwcService_GetDisplayIDFromConnectorID(HWCSHANDLE hwcs, status_t HwcService_EnableDRMCommit(HWCSHANDLE hwcs, uint32_t enable, uint32_t display_id); +status_t HwcService_ResetDrmMaster(HWCSHANDLE hwcs, uint32_t drop_master); + // The control enables a the protected video subsystem to control when to // replace any // encrypted content with a default bitmap (usually black). diff --git a/os/android/libhwcservice/icontrols.cpp b/os/android/libhwcservice/icontrols.cpp index 9a59aef1..ec1f93a4 100644 --- a/os/android/libhwcservice/icontrols.cpp +++ b/os/android/libhwcservice/icontrols.cpp @@ -58,6 +58,7 @@ class BpControls : public BpInterface { TRANSACT_VIDEO_SET_HDCP_SRM_FOR_DISPLAY, TRANSACT_GET_DISPLAYID_FROM_CONNECTORID, TRANSACT_ENABLE_DRM_COMMIT, + TRANSACT_RESET_DRM_MASTER, TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION, TRANSACT_VIDEO_DISABLE_ENCRYPTED_SESSION, TRANSACT_VIDEO_DISABLE_ALL_ENCRYPTED_SESSIONS, @@ -458,6 +459,19 @@ class BpControls : public BpInterface { return (uint32_t)(reply.readInt32()); } + bool ResetDrmMaster(bool drop_master) override { + Parcel data; + Parcel reply; + data.writeInterfaceToken(IControls::getInterfaceDescriptor()); + data.writeInt32(drop_master); + + status_t ret = remote()->transact(TRANSACT_RESET_DRM_MASTER, data, &reply); + if (ret != NO_ERROR) { + ALOGW("%s() transact failed: %d", __FUNCTION__, ret); + } + return (uint32_t)(reply.readInt32()); + } + status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID) override { Parcel data; @@ -801,6 +815,13 @@ status_t BnControls::onTransact(uint32_t code, const Parcel &data, reply->writeInt32(ret); return NO_ERROR; } + case BpControls::TRANSACT_RESET_DRM_MASTER: { + CHECK_INTERFACE(IControls, data, reply); + bool drop_master = data.readInt32(); + bool ret = this->ResetDrmMaster(drop_master); + reply->writeInt32(ret); + return NO_ERROR; + } case BpControls::TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION: { CHECK_INTERFACE(IControls, data, reply); uint32_t sessionID = data.readInt32(); diff --git a/os/android/libhwcservice/icontrols.h b/os/android/libhwcservice/icontrols.h index c8c0c49f..db8f90c3 100644 --- a/os/android/libhwcservice/icontrols.h +++ b/os/android/libhwcservice/icontrols.h @@ -81,6 +81,8 @@ class IControls : public android::IInterface { virtual bool EnableDRMCommit(bool enable, uint32_t display_id) = 0; + virtual bool ResetDrmMaster(bool drop_master) = 0; + virtual status_t VideoEnableEncryptedSession(uint32_t sessionID, uint32_t instanceID) = 0; virtual status_t VideoDisableAllEncryptedSessions(uint32_t sessionID) = 0; diff --git a/public/gpudevice.h b/public/gpudevice.h index b8ff7d40..9d113d22 100644 --- a/public/gpudevice.h +++ b/public/gpudevice.h @@ -117,6 +117,8 @@ class GpuDevice : public HWCThread { void ResetAllDisplayCommit(bool enable); + void MarkDisplayForFirstCommit(); + enum InitializationType { kUnInitialized = 0, // Nothing Initialized. kInitialized = 1 << 1 // Everything Initialized diff --git a/public/hwclayer.h b/public/hwclayer.h index f2dc0b3b..b8e4af30 100644 --- a/public/hwclayer.h +++ b/public/hwclayer.h @@ -348,7 +348,7 @@ struct HwcLayer { kVisible | kSurfaceDamageChanged | kVisibleRegionChanged | kZorderChanged; int layer_cache_ = kLayerAttributesChanged | kDisplayFrameRectChanged; bool is_cursor_layer_ = false; - uint32_t solid_color_ = 0; + uint32_t solid_color_ = 0xff; HWCLayerCompositionType composition_type_ = Composition_Device; }; diff --git a/public/nativedisplay.h b/public/nativedisplay.h index c43bcf92..bad3251c 100644 --- a/public/nativedisplay.h +++ b/public/nativedisplay.h @@ -428,6 +428,9 @@ class NativeDisplay { return false; } + virtual void MarkFirstCommit() { + } + protected: friend class PhysicalDisplay; friend class GpuDevice; diff --git a/wsi/drm/drmdisplay.cpp b/wsi/drm/drmdisplay.cpp index a98e89fa..23c2b555 100644 --- a/wsi/drm/drmdisplay.cpp +++ b/wsi/drm/drmdisplay.cpp @@ -16,6 +16,7 @@ #include "drmdisplay.h" +#include #include #include #include @@ -133,6 +134,7 @@ void DrmDisplay::DrmConnectorGetDCIP3Support( edid = (uint8_t *)blob->data; if (!edid) { + drmModeFreePropertyBlob(blob); return; } @@ -153,6 +155,66 @@ void DrmDisplay::DrmConnectorGetDCIP3Support( return; } +void DrmDisplay::GetEDIDDisplayData(const ScopedDrmObjectPropertyPtr &props) { + uint8_t *edid = NULL; + uint64_t edid_blob_id; + struct edid_display_data display_data[4]; + drmModePropertyBlobPtr blob; + + GetDrmObjectPropertyValue("EDID", props, &edid_blob_id); + blob = drmModeGetPropertyBlob(gpu_fd_, edid_blob_id); + if (!blob) { + return; + } + + edid = (uint8_t *)blob->data; + if (!edid) { + return; + } + std::memset(display_data, 0, sizeof(display_data)); + std::memcpy((void *)display_data, (void *)(edid + 54), + sizeof(edid_display_data) * 4); + + for (int i = 0; i < 4; i++) { + if (!(display_data[i].indicate == 0x0000 && + display_data[i].reserved1 == 0x00 && + display_data[i].reserved2 == 0x00)) + continue; + + if (display_data[i].tag_number == 0xfc) { + display_name_.clear(); + size_t display_desc_size = + sizeof(((struct edid_display_data *)0)->desc_data); + size_t display_desc_str_size = + strchrnul((char *)display_data[i].desc_data, '\n') - + (char *)display_data[i].desc_data; + size_t display_desc_copy_size = display_desc_str_size > display_desc_size + ? display_desc_size + : display_desc_str_size; + display_name_.assign((char *)display_data[i].desc_data, + display_desc_copy_size); + } + } + + ITRACE("Got EDID display name \"%s\"\n", display_name_.c_str()); +} + +/* +* Check limited monitors exposing some modes which not +* be supported by monitor hardware actually. Limited monitors +* be defined in HWC_LIMITED_MONITOR_LIST. +*/ +bool DrmDisplay::CheckLimitedMonitor() { + for (unsigned int i = 0; i < HWC_LIMITED_MONITOR_LIST.size(); ++i) { + if (display_name_.compare(HWC_LIMITED_MONITOR_LIST[i]) == 0) { + ITRACE("Got a limited monitor: %s\n", + HWC_LIMITED_MONITOR_LIST[i].c_str()); + return true; + } + } + return false; +} + bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info, const drmModeConnector *connector, uint32_t config) { @@ -230,6 +292,8 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info, ITRACE("DCIP3 support not available"); } + GetEDIDDisplayData(connector_props); + PhysicalDisplay::Connect(); SetHDCPState(desired_protection_support_, content_type_); @@ -488,6 +552,14 @@ bool DrmDisplay::ContainConnector(const uint32_t connector_id) { return (connector_ == connector_id); } +void DrmDisplay::TraceFirstCommit() { + struct timeval te; + gettimeofday(&te, NULL); // get current time + long long milliseconds = + te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds + ITRACE("First frame is Committed at %lld.", milliseconds); +} + bool DrmDisplay::Commit( const DisplayPlaneStateList &composition_planes, const DisplayPlaneStateList &previous_composition_planes, @@ -506,6 +578,10 @@ bool DrmDisplay::Commit( return false; } + // Disable not-in-used plane once DRM master is reset + if (first_commit_) + display_queue_->ResetPlanes(pset.get()); + if (display_state_ & kNeedsModeset) { if (!ApplyPendingModeset(pset.get())) { ETRACE("Failed to Modeset."); @@ -537,7 +613,10 @@ bool DrmDisplay::Commit( *commit_fence = 0; } #endif - + if (first_commit_) { + TraceFirstCommit(); + first_commit_ = false; + } return true; } @@ -565,8 +644,14 @@ bool DrmDisplay::CommitFrame( comp_plane.GetRotationType(); if ((plane_transform != kIdentity) && (rotation_type == DisplayPlaneState::RotationType::kDisplayRotation)) { - HwcRect rotated_rect = - RotateScaleRect(display_rect, width_, height_, plane_transform); + HwcRect rotated_rect; + if (layer->IsVideoLayer()) { + rotated_rect = + RotateRect(display_rect, width_, height_, plane_transform); + } else { + rotated_rect = + RotateScaleRect(display_rect, width_, height_, plane_transform); + } layer->SetDisplayFrame(rotated_rect); } @@ -588,7 +673,6 @@ bool DrmDisplay::CommitFrame( DrmPlane *plane = static_cast(comp_plane.GetDisplayPlane()); if (plane->InUse()) continue; - plane->Disable(pset); } @@ -621,7 +705,6 @@ void DrmDisplay::SetDrmModeInfo(const std::vector &mode_info) { #endif modes_.emplace_back(mode_info[i]); } - SPIN_UNLOCK(display_lock_); } @@ -660,8 +743,10 @@ void DrmDisplay::GetDrmObjectProperty(const char *name, ScopedDrmPropertyPtr property(drmModeGetProperty(gpu_fd_, props->props[i])); if (property && !strcmp(property->name, name)) { *id = property->prop_id; + property.reset(); break; } + property.reset(); } if (!(*id)) ETRACE("Could not find property %s", name); @@ -689,8 +774,10 @@ void DrmDisplay::GetDrmHDCPObjectProperty( } } } + property.reset(); break; } + property.reset(); } if (!(*id)) ETRACE("Could not find property %s", name); @@ -704,8 +791,10 @@ void DrmDisplay::GetDrmObjectPropertyValue( ScopedDrmPropertyPtr property(drmModeGetProperty(gpu_fd_, props->props[i])); if (property && !strcmp(property->name, name)) { *value = props->prop_values[i]; + property.reset(); break; } + property.reset(); } if (!(*value)) ETRACE("Could not find property value %s", name); @@ -1045,11 +1134,14 @@ bool DrmDisplay::PopulatePlanes( drmModeGetPlane(gpu_fd_, plane_resources->planes[i])); if (!drm_plane) { ETRACE("Failed to get plane "); + plane_resources.reset(); return false; } - if (!(pipe_bit & drm_plane->possible_crtcs)) + if (!(pipe_bit & drm_plane->possible_crtcs)) { + drm_plane.reset(); continue; + } uint32_t formats_size = drm_plane->count_formats; plane_ids.insert(drm_plane->plane_id); @@ -1061,7 +1153,7 @@ bool DrmDisplay::PopulatePlanes( bool use_modifier = true; #ifdef MODIFICATOR_WA - use_modifier = (manager_->GetConnectedPhysicalDisplayCount() < 3); + use_modifier = (manager_->GetConnectedPhysicalDisplayCount() < 2); if (i >= 2) use_modifier = false; #endif @@ -1072,10 +1164,13 @@ bool DrmDisplay::PopulatePlanes( overlay_planes.emplace_back(plane.release()); } } + + drm_plane.reset(); } if (overlay_planes.empty()) { ETRACE("Failed to get primary plane for display %d", crtc_id_); + plane_resources.reset(); return false; } @@ -1089,6 +1184,7 @@ bool DrmDisplay::PopulatePlanes( overlay_planes.emplace_back(cursor_plane.release()); } + plane_resources.reset(); return true; } diff --git a/wsi/drm/drmdisplay.h b/wsi/drm/drmdisplay.h index d02cb3eb..415135ff 100644 --- a/wsi/drm/drmdisplay.h +++ b/wsi/drm/drmdisplay.h @@ -129,6 +129,12 @@ class DrmDisplay : public PhysicalDisplay { return planes_updated_; } + void MarkFirstCommit() override { + first_commit_ = true; + } + + bool CheckLimitedMonitor(); + private: void ShutDownPipe(); void GetDrmObjectPropertyValue(const char *name, @@ -161,6 +167,9 @@ class DrmDisplay : public PhysicalDisplay { std::vector FindExtendedBlocksForTag(uint8_t *edid, uint8_t block_tag); void DrmConnectorGetDCIP3Support(const ScopedDrmObjectPropertyPtr &props); + void GetEDIDDisplayData(const ScopedDrmObjectPropertyPtr &props); + + void TraceFirstCommit(); uint32_t crtc_id_ = 0; uint32_t mmWidth_ = 0; @@ -188,6 +197,8 @@ class DrmDisplay : public PhysicalDisplay { int64_t broadcastrgb_automatic_ = -1; uint32_t flags_ = DRM_MODE_ATOMIC_ALLOW_MODESET; bool planes_updated_ = false; + bool first_commit_ = false; + std::string display_name_; HWCContentProtection current_protection_support_ = HWCContentProtection::kUnSupported; HWCContentProtection desired_protection_support_ = diff --git a/wsi/drm/drmdisplaymanager.cpp b/wsi/drm/drmdisplaymanager.cpp index 62f874d0..adef66ef 100644 --- a/wsi/drm/drmdisplaymanager.cpp +++ b/wsi/drm/drmdisplaymanager.cpp @@ -75,13 +75,21 @@ bool DrmDisplayManager::Initialize() { } ScopedDrmResourcesPtr res(drmModeGetResources(fd_)); - if (res->count_crtcs == 0) + if (!res) { + ETRACE("Failed to get resources"); + return false; + } + + if (res->count_crtcs == 0) { + res.reset(); return false; + } for (int32_t i = 0; i < res->count_crtcs; ++i) { ScopedDrmCrtcPtr c(drmModeGetCrtc(fd_, res->crtcs[i])); if (!c) { ETRACE("Failed to get crtc %d", res->crtcs[i]); + res.reset(); return false; } @@ -89,12 +97,15 @@ bool DrmDisplayManager::Initialize() { new DrmDisplay(fd_, i, c->crtc_id, this)); displays_.emplace_back(std::move(display)); + + c.reset(); } #ifndef DISABLE_HOTPLUG_NOTIFICATION hotplug_fd_ = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (hotplug_fd_ < 0) { ETRACE("Failed to create socket for hot plug monitor. %s", PRINTERROR()); + res.reset(); return true; } @@ -108,6 +119,7 @@ bool DrmDisplayManager::Initialize() { if (ret) { ETRACE("Failed to bind sockaddr_nl and hot plug monitor fd. %s", PRINTERROR()); + res.reset(); return true; } @@ -115,6 +127,7 @@ bool DrmDisplayManager::Initialize() { #endif IHOTPLUGEVENTTRACE("DisplayManager Initialization succeeded."); + res.reset(); return true; } @@ -233,9 +246,12 @@ bool DrmDisplayManager::UpdateDisplayState() { break; } // check if a monitor is connected. - if (connector->connection != DRM_MODE_CONNECTED) + if (connector->connection != DRM_MODE_CONNECTED) { + connector.reset(); continue; + } connected_display_count_++; + connector.reset(); } for (uint32_t i = 0; i < total_connectors; ++i) { @@ -246,15 +262,20 @@ bool DrmDisplayManager::UpdateDisplayState() { break; } // check if a monitor is connected. - if (connector->connection != DRM_MODE_CONNECTED) + if (connector->connection != DRM_MODE_CONNECTED) { + connector.reset(); continue; + } // Ensure we have atleast one valid mode. - if (connector->count_modes == 0) + if (connector->count_modes == 0) { + connector.reset(); continue; + } if (connector->encoder_id == 0) { no_encoder.emplace_back(i); + connector.reset(); continue; } @@ -285,11 +306,21 @@ bool DrmDisplayManager::UpdateDisplayState() { encoder->crtc_id, display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - display->SetDrmModeInfo(mode); + if (display->CheckLimitedMonitor()) { + // only expose the preferred mode for limited monitor + std::vector limited_mode( + 1, connector->modes[preferred_mode]); + display->SetDrmModeInfo(limited_mode); + } else { + display->SetDrmModeInfo(mode); + } break; } } } + + encoder.reset(); + connector.reset(); } // Deal with connectors with encoder_id == 0. @@ -330,11 +361,22 @@ bool DrmDisplayManager::UpdateDisplayState() { IHOTPLUGEVENTTRACE("Connected with crtc: %d pipe:%d \n", display->CrtcId(), display->GetDisplayPipe()); // Set the modes supported for each display - display->SetDrmModeInfo(mode); + if (display->CheckLimitedMonitor()) { + // only expose the preferred mode for limited monitor + std::vector limited_mode( + 1, connector->modes[preferred_mode]); + display->SetDrmModeInfo(limited_mode); + } else { + display->SetDrmModeInfo(mode); + } break; } } + + encoder.reset(); } + + connector.reset(); } for (auto &display : displays_) { @@ -364,6 +406,7 @@ bool DrmDisplayManager::UpdateDisplayState() { if (device_.IsReservedDrmPlane()) RemoveUnreservedPlanes(); + res.reset(); return true; } diff --git a/wsi/drm/drmplane.cpp b/wsi/drm/drmplane.cpp index 389b1ac4..9c49a085 100644 --- a/wsi/drm/drmplane.cpp +++ b/wsi/drm/drmplane.cpp @@ -216,6 +216,7 @@ bool DrmPlane::Initialize(uint32_t gpu_fd, const std::vector& formats, drmModeGetPropertyBlob(gpu_fd, in_formats_prop_value); if (blob == nullptr || blob->data == nullptr) { ETRACE("Unable to get property data\n"); + drmModeFreePropertyBlob(blob); return false; } @@ -341,7 +342,7 @@ bool DrmPlane::UpdateProperties(drmModeAtomicReqPtr property_set, if (rotation_prop_.id) { uint32_t rotation = 0; - uint32_t transform = layer->GetPlaneTransform(); + uint32_t transform = layer->GetMergedTransform(); if (transform & kTransform90) { rotation |= DRM_MODE_ROTATE_90; if (transform & kReflectX) @@ -455,7 +456,7 @@ bool DrmPlane::ValidateLayer(const OverlayLayer* layer) { } bool zero_rotation = false; - uint32_t transform = layer->GetPlaneTransform(); + uint32_t transform = layer->GetMergedTransform(); if (transform == kIdentity) { zero_rotation = true; } diff --git a/wsi/drm/drmplane.h b/wsi/drm/drmplane.h index 52c0b342..3a3d07ef 100644 --- a/wsi/drm/drmplane.h +++ b/wsi/drm/drmplane.h @@ -22,12 +22,11 @@ #include -#include - #include #include "displayplane.h" #include "drmbuffer.h" +#include "drmscopedtypes.h" namespace hwcomposer { diff --git a/wsi/physicaldisplay.cpp b/wsi/physicaldisplay.cpp index c051a245..7fad3e80 100644 --- a/wsi/physicaldisplay.cpp +++ b/wsi/physicaldisplay.cpp @@ -377,7 +377,7 @@ int PhysicalDisplay::RegisterVsyncCallback( void PhysicalDisplay::RegisterRefreshCallback( std::shared_ptr callback, uint32_t display_id) { - return display_queue_->RegisterRefreshCallback(callback, display_id); + display_queue_->RegisterRefreshCallback(callback, display_id); } void PhysicalDisplay::RegisterHotPlugCallback( diff --git a/wsi/physicaldisplay.h b/wsi/physicaldisplay.h index 471f13ca..4fd91f7e 100644 --- a/wsi/physicaldisplay.h +++ b/wsi/physicaldisplay.h @@ -306,5 +306,15 @@ class PhysicalDisplay : public NativeDisplay, public DisplayPlaneHandler { uint32_t config_ = DEFAULT_CONFIG_ID; }; +struct __attribute__((packed)) edid_display_data { + uint16_t indicate; + uint8_t reserved1; + uint8_t tag_number; + uint8_t reserved2; + uint8_t desc_data[13]; +}; + +const std::vector HWC_LIMITED_MONITOR_LIST{"TD2230 Series"}; + } // namespace hwcomposer #endif // WSI_PHYSICALDISPLAY_H_