X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=common%2Fcore%2Foverlaylayer.cpp;h=39c2af64a7ba92c96f1e9907daa86d8b72f23c4d;hb=748c488f85ed609731b9a3c9c3f993df6da27d88;hp=f8a335896dd8811b05d2e5bf33bd27abdb772fcf;hpb=54abe7231d780d5d5eb2ce17274867f6c8cad7e7;p=android-x86%2Fexternal-IA-Hardware-Composer.git diff --git a/common/core/overlaylayer.cpp b/common/core/overlaylayer.cpp index f8a3358..39c2af6 100644 --- a/common/core/overlaylayer.cpp +++ b/common/core/overlaylayer.cpp @@ -20,9 +20,12 @@ #include #include +#include +#include #include "hwcutils.h" +#include "nativebufferhandler.h" #include "resourcemanager.h" namespace hwcomposer { @@ -41,50 +44,76 @@ OverlayLayer::ImportedBuffer::ImportedBuffer( void OverlayLayer::SetAcquireFence(int32_t acquire_fence) { // Release any existing fence. - if (imported_buffer_->acquire_fence_ > 0) { - close(imported_buffer_->acquire_fence_); - } + if (imported_buffer_.get()) { + if (imported_buffer_->acquire_fence_ > 0) { + close(imported_buffer_->acquire_fence_); + } - imported_buffer_->acquire_fence_ = acquire_fence; + imported_buffer_->acquire_fence_ = acquire_fence; + } } int32_t OverlayLayer::GetAcquireFence() const { - return imported_buffer_->acquire_fence_; + if (imported_buffer_.get()) { + return imported_buffer_->acquire_fence_; + } else + return -1; } int32_t OverlayLayer::ReleaseAcquireFence() const { - int32_t fence = imported_buffer_->acquire_fence_; - imported_buffer_->acquire_fence_ = -1; - return fence; + if (imported_buffer_.get()) { + int32_t fence = imported_buffer_->acquire_fence_; + imported_buffer_->acquire_fence_ = -1; + return fence; + } else { + return -1; + } } OverlayBuffer* OverlayLayer::GetBuffer() const { - if (imported_buffer_->buffer_.get() == NULL) - ETRACE("hwc layer get NullBuffer"); - return imported_buffer_->buffer_.get(); + if (imported_buffer_.get()) { + if (imported_buffer_->buffer_.get() == NULL) + ETRACE("hwc layer get NullBuffer"); + + return imported_buffer_->buffer_.get(); + } else { + return NULL; + } +} + +std::shared_ptr& OverlayLayer::GetSharedBuffer() const { + return imported_buffer_->buffer_; } void OverlayLayer::SetBuffer(HWCNativeHandle handle, int32_t acquire_fence, ResourceManager* resource_manager, - bool register_buffer) { + bool register_buffer, + FrameBufferManager* frame_buffer_manager) { std::shared_ptr buffer(NULL); - if (resource_manager) { - buffer = resource_manager->FindCachedBuffer(GETNATIVEBUFFER(handle)); + uint32_t id; + + if (resource_manager && register_buffer) { + uint32_t gpu_fd = resource_manager->GetNativeBufferHandler()->GetFd(); + id = GetNativeBuffer(gpu_fd, handle); + buffer = resource_manager->FindCachedBuffer(id); } if (buffer == NULL) { buffer = OverlayBuffer::CreateOverlayBuffer(); buffer->InitializeFromNativeHandle(handle, resource_manager, - register_buffer); - if (register_buffer) { - resource_manager->RegisterBuffer(GETNATIVEBUFFER(handle), buffer); + frame_buffer_manager); + if (resource_manager && register_buffer) { + resource_manager->RegisterBuffer(id, buffer); } + } else { + buffer->SetOriginalHandle(handle); } + + buffer->SetDataSpace(dataspace_); + imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence)); - if (!register_buffer) { - ValidateForOverlayUsage(); - } + ValidateForOverlayUsage(); } void OverlayLayer::SetBlending(HWCBlending blending) { @@ -103,114 +132,65 @@ void OverlayLayer::SetDisplayFrame(const HwcRect& display_frame) { display_frame_width_ = display_frame.right - display_frame.left; display_frame_height_ = display_frame.bottom - display_frame.top; display_frame_ = display_frame; - surface_damage_ = display_frame; +} + +void OverlayLayer::SetTransform(uint32_t transform) { + plane_transform_ = transform; + transform_ = transform; } void OverlayLayer::ValidateTransform(uint32_t transform, uint32_t display_transform) { - if (transform & kTransform90) { - if (transform & kReflectX) { - plane_transform_ |= kReflectX; - } - - if (transform & kReflectY) { - plane_transform_ |= kReflectY; - } - - switch (display_transform) { - case kRotate90: - plane_transform_ |= kTransform180; - break; - case kRotate180: - plane_transform_ |= kTransform270; - break; - case kRotateNone: - plane_transform_ |= kTransform90; - break; - default: - break; - } - } else if (transform & kTransform180) { - switch (display_transform) { - case kRotate90: - plane_transform_ |= kTransform270; - break; - case kRotate270: - plane_transform_ |= kTransform90; - break; - case kRotateNone: - plane_transform_ |= kTransform180; - break; - default: - break; - } - } else if (transform & kTransform270) { - switch (display_transform) { - case kRotate270: - plane_transform_ |= kTransform180; - break; - case kRotate180: - plane_transform_ |= kTransform90; - break; - case kRotateNone: - plane_transform_ |= kTransform270; - break; - default: - break; - } + std::map tmap = {{kIdentity, 0}, + {kTransform90, 1}, + {kTransform180, 2}, + {kTransform270, 3}}; + std::vector inv_tmap = {kIdentity, kTransform90, kTransform180, + kTransform270}; + + int mdisplay_transform = display_transform; + int mtransform = + transform & (kIdentity | kTransform90 | kTransform180 | kTransform270); + + if (tmap.find(mtransform) != tmap.end()) { + mtransform = tmap[mtransform]; } else { - if (display_transform == kRotate90) { - if (transform & kReflectX) { - plane_transform_ |= kReflectX; - } - - if (transform & kReflectY) { - plane_transform_ |= kReflectY; - } - - plane_transform_ |= kTransform90; - } else { - switch (display_transform) { - case kRotate270: - plane_transform_ |= kTransform270; - break; - case kRotate180: - plane_transform_ |= kReflectY; - break; - default: - break; - } - } + // reaching here indicates that transform is + // is an OR of multiple values + // Assign Identity in this case + mtransform = kIdentity; } -} -void OverlayLayer::UpdateSurfaceDamage(HwcLayer* layer) { - if (!gpu_rendered_) { - surface_damage_ = display_frame_; - return; + if (tmap.find(mdisplay_transform) != tmap.end()) { + mdisplay_transform = tmap[mdisplay_transform]; + } else { + mdisplay_transform = kIdentity; } - if ((state_ & kClearSurface) || (state_ & kDimensionsChanged) || - (transform_ != kIdentity)) { - surface_damage_ = display_frame_; - return; - } + // 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; - surface_damage_ = layer->GetSurfaceDamage(); + if (plane_transform_ & kTransform90) { + if (transform & kReflectX) + plane_transform_ |= kReflectX; + + if (transform & kReflectY) + plane_transform_ |= kReflectY; + } } void OverlayLayer::InitializeState(HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, HWCRotation rotation, - bool handle_constraints) { + uint32_t max_height, uint32_t rotation, + bool handle_constraints, + FrameBufferManager* frame_buffer_manager) { transform_ = layer->GetTransform(); if (rotation != kRotateNone) { ValidateTransform(layer->GetTransform(), rotation); - // Remove this in case we enable support in future - // to apply display rotation at pipe level. - transform_ = plane_transform_; } else { plane_transform_ = transform_; } @@ -221,22 +201,60 @@ void OverlayLayer::InitializeState(HwcLayer* layer, source_crop_width_ = layer->GetSourceCropWidth(); source_crop_height_ = layer->GetSourceCropHeight(); source_crop_ = layer->GetSourceCrop(); + dataspace_ = layer->GetDataSpace(); blending_ = layer->GetBlending(); - SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(), - resource_manager, true); - ValidateForOverlayUsage(); - if (previous_layer) { - ValidatePreviousFrameState(previous_layer, layer); + surface_damage_ = layer->GetLayerDamage(); + + solid_color_ = layer->GetSolidColor(); + + if (previous_layer && layer->HasZorderChanged()) { + if (previous_layer->actual_composition_ == kGpu) { + CalculateRect(previous_layer->display_frame_, surface_damage_); + bool force_partial_clear = true; + // We can skip Clear in case display frame, transforms are same. + if (previous_layer->display_frame_ == display_frame_ && + transform_ == previous_layer->transform_ && + plane_transform_ == previous_layer->plane_transform_) { + force_partial_clear = false; + } + + if (force_partial_clear) { + state_ |= kForcePartialClear; + } + } else if (!layer->IsCursorLayer()) { + state_ |= kNeedsReValidation; + } + } + + if (layer->GetNativeHandle()) { + SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(), + resource_manager, true, frame_buffer_manager); + } else if (Composition_SolidColor == layer->GetLayerCompositionType()) { + type_ = kLayerSolidColor; + source_crop_width_ = layer->GetDisplayFrameWidth(); + source_crop_height_ = layer->GetDisplayFrameHeight(); + source_crop_.left = source_crop_.top = 0; + source_crop_.right = source_crop_width_; + source_crop_.top = source_crop_height_; + imported_buffer_.reset(NULL); + } else { + ETRACE( + "HWC don't support a layer with no buffer handle except in SolidColor " + "type"); } - if (layer->HasContentAttributesChanged() || - layer->HasLayerAttributesChanged() || !layer->IsValidated()) { - state_ |= kClearSurface; - state_ |= kLayerContentChanged; + if (!surface_damage_.empty()) { + if (type_ == kLayerCursor) { + const std::shared_ptr& buffer = imported_buffer_->buffer_; + surface_damage_.right = surface_damage_.left + buffer->GetWidth(); + surface_damage_.bottom = surface_damage_.top + buffer->GetHeight(); + } } if (!handle_constraints) { - UpdateSurfaceDamage(layer); + if (previous_layer) { + ValidatePreviousFrameState(previous_layer, layer); + } return; } @@ -271,32 +289,46 @@ void OverlayLayer::InitializeState(HwcLayer* layer, display_frame_.right = right_source_constraint; } + // Handle case where we might be using logical and Mosaic together. display_frame_.left = (display_frame_.left - left_source_constraint) + left_constraint; display_frame_.right = (display_frame_.right - left_source_constraint) + left_constraint; + IMOSAICDISPLAYTRACE( + "display_frame_ %d %d %d %d left_source_constraint: %d " + "left_constraint: %d \n", + display_frame_.left, display_frame_.right, display_frame_.top, + display_frame_.bottom, left_source_constraint, left_constraint); display_frame_.bottom = std::min(max_height, static_cast(display_frame_.bottom)); display_frame_width_ = display_frame_.right - display_frame_.left; display_frame_height_ = display_frame_.bottom - display_frame_.top; - UpdateSurfaceDamage(layer); - if (gpu_rendered_) { - // If viewport and layer doesn't interact we can avoid re-rendering - // this layer. - if (AnalyseOverlap(surface_damage_, display_frame_) != kOutside) { - surface_damage_.left = - std::max(surface_damage_.left, display_frame_.left); - surface_damage_.right = - std::min(surface_damage_.right, display_frame_.right); - surface_damage_.top = std::max(surface_damage_.top, display_frame_.top); - surface_damage_.bottom = - std::min(surface_damage_.bottom, display_frame_.bottom); - } else { - surface_damage_ = HwcRect(0, 0, 0, 0); - } + if ((surface_damage_.left < display_frame_.left) && + (surface_damage_.right > display_frame_.left)) { + surface_damage_.left = display_frame_.left; + } + + if (surface_damage_.right > display_frame_.right) { + surface_damage_.right = display_frame_.right; + } + + if (AnalyseOverlap(surface_damage_, display_frame_) != kOutside) { + surface_damage_.bottom = + std::min(surface_damage_.bottom, display_frame_.bottom); + surface_damage_.right = + std::min(surface_damage_.right, display_frame_.right); + surface_damage_.left = + std::max(surface_damage_.left, display_frame_.left); + } else { + surface_damage_.reset(); } + IMOSAICDISPLAYTRACE( + "surface_damage_ %d %d %d %d left_source_constraint: %d " + "left_constraint: %d \n", + surface_damage_.left, surface_damage_.right, surface_damage_.top, + surface_damage_.bottom, left_source_constraint, left_constraint); // split the source in proportion of frame rect offset for sub displays as: // 1. the original source size may be different with the original frame @@ -315,34 +347,44 @@ void OverlayLayer::InitializeState(HwcLayer* layer, source_crop_height_ = static_cast(ceilf(source_crop_.bottom) - static_cast(source_crop_.top)); } + + if (previous_layer) { + ValidatePreviousFrameState(previous_layer, layer); + } } void OverlayLayer::InitializeFromHwcLayer( HwcLayer* layer, ResourceManager* resource_manager, OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index, - uint32_t max_height, HWCRotation rotation, bool handle_constraints) { + uint32_t max_height, uint32_t rotation, bool handle_constraints, + FrameBufferManager* frame_buffer_manager) { 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, rotation, handle_constraints, + frame_buffer_manager); } 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, - HWCRotation rotation, bool handle_constraints) { + const HwcRect& display_frame, uint32_t max_height, uint32_t rotation, + bool handle_constraints, FrameBufferManager* frame_buffer_manager) { SetDisplayFrame(display_frame); InitializeState(layer, resource_manager, previous_layer, z_order, layer_index, - max_height, rotation, handle_constraints); + max_height, rotation, handle_constraints, + frame_buffer_manager); } void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, HwcLayer* layer) { - OverlayBuffer* buffer = imported_buffer_->buffer_.get(); - if (buffer->GetFormat() != rhs->imported_buffer_->buffer_->GetFormat()) - return; + OverlayBuffer* buffer = NULL; + if (imported_buffer_.get()) + buffer = imported_buffer_->buffer_.get(); + + supported_composition_ = rhs->supported_composition_; + actual_composition_ = rhs->actual_composition_; bool content_changed = false; bool rect_changed = layer->HasDisplayRectChanged(); @@ -351,35 +393,59 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, state_ |= kSourceRectChanged; // We expect cursor plane to support alpha always. - if (rhs->gpu_rendered_ || (type_ == kLayerCursor)) { - content_changed = rect_changed || source_rect_changed; + if ((actual_composition_ & kGpu) || (type_ == kLayerCursor) || + (type_ == kLayerSolidColor)) { + if (actual_composition_ & kGpu) { + content_changed = rect_changed || source_rect_changed; + // This layer has replaced an existing layer, let's make sure + // we re-draw this and previous layer regions. + if (!layer->IsValidated()) { + content_changed = true; + CalculateRect(rhs->display_frame_, surface_damage_); + } else if (!content_changed) { + if ((buffer && rhs->imported_buffer_.get() && + (buffer->GetFormat() != + rhs->imported_buffer_->buffer_->GetFormat())) || + (alpha_ != rhs->alpha_) || (blending_ != rhs->blending_) || + (transform_ != rhs->transform_)) { + content_changed = true; + } + } + } else if (type_ == kLayerCursor) { + if (layer->HasLayerAttributesChanged()) { + state_ |= kNeedsReValidation; + } + } } else { + // Ensure the buffer can be supported by display for direct + // scanout. + if (!rhs->imported_buffer_.get()) { + state_ |= kNeedsReValidation; + return; + } else if (buffer && (buffer->GetFormat() != + rhs->imported_buffer_->buffer_->GetFormat())) { + state_ |= kNeedsReValidation; + return; + } + // If previous layer was opaque and we have alpha now, // let's mark this layer for re-validation. Plane // supporting XRGB format might not necessarily support // transparent planes. We assume plane supporting // ARGB will support XRGB. - if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_)) + if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_)) { + state_ |= kNeedsReValidation; return; + } - if (blending_ != rhs->blending_) + if (blending_ != rhs->blending_) { + state_ |= kNeedsReValidation; return; + } if (rect_changed || layer->HasLayerAttributesChanged()) { - if (layer->IsValidated()) { - return; - } - - if (rhs->transform_ != transform_) { - return; - } - - if ((rhs->display_frame_.left != display_frame_.left) || - (rhs->display_frame_.right != display_frame_.right) || - (rhs->display_frame_.top != display_frame_.top) || - (rhs->display_frame_.bottom != display_frame_.bottom)) { - return; - } + state_ |= kNeedsReValidation; + return; } if (source_rect_changed) { @@ -387,32 +453,51 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs, // shouldn't impact the plane composition results. if ((source_crop_width_ != rhs->source_crop_width_) || (source_crop_height_ != rhs->source_crop_height_)) { + state_ |= kNeedsReValidation; return; } } } - state_ &= ~kLayerAttributesChanged; - gpu_rendered_ = rhs->gpu_rendered_; - if (!rect_changed) { state_ &= ~kDimensionsChanged; } - if (!layer->HasVisibleRegionChanged() && - !layer->HasSurfaceDamageRegionChanged() && - !layer->HasLayerContentChanged() && !content_changed) { + if (!layer->HasVisibleRegionChanged() && !content_changed && + surface_damage_.empty() && !layer->HasLayerContentChanged() && + !(state_ & kNeedsReValidation)) { state_ &= ~kLayerContentChanged; } } void OverlayLayer::ValidateForOverlayUsage() { const std::shared_ptr& buffer = imported_buffer_->buffer_; - if (buffer->GetUsage() & kLayerCursor) { - type_ = kLayerCursor; - } else if (buffer->IsVideoBuffer()) { - type_ = kLayerVideo; + type_ = buffer->GetUsage(); +} + +void OverlayLayer::CloneLayer(const OverlayLayer* layer, + const HwcRect& display_frame, + ResourceManager* resource_manager, + uint32_t z_order, + FrameBufferManager* frame_buffer_manager) { + int32_t fence = layer->GetAcquireFence(); + int32_t aquire_fence = 0; + if (fence > 0) { + aquire_fence = dup(fence); } + SetDisplayFrame(display_frame); + SetSourceCrop(layer->GetSourceCrop()); + SetBuffer(layer->GetBuffer()->GetOriginalHandle(), aquire_fence, + resource_manager, true, frame_buffer_manager); + ValidateForOverlayUsage(); + surface_damage_ = layer->GetSurfaceDamage(); + transform_ = layer->transform_; + plane_transform_ = layer->plane_transform_; + alpha_ = layer->alpha_; + layer_index_ = z_order; + z_order_ = z_order; + blending_ = layer->blending_; + solid_color_ = layer->solid_color_; } void OverlayLayer::Dump() { @@ -435,8 +520,8 @@ void OverlayLayer::Dump() { DUMPTRACE("Transform: kReflectX."); if (transform_ & kReflectY) DUMPTRACE("Transform: kReflectY."); - if (transform_ & kReflectY) - DUMPTRACE("Transform: kReflectY."); + if (transform_ & kTransform90) + DUMPTRACE("Transform: kTransform90."); else if (transform_ & kTransform180) DUMPTRACE("Transform: kTransform180."); else if (transform_ & kTransform270) @@ -450,7 +535,11 @@ void OverlayLayer::Dump() { DUMPTRACE("SourceHeight: %d", source_crop_height_); DUMPTRACE("DstWidth: %d", display_frame_width_); DUMPTRACE("DstHeight: %d", display_frame_height_); - DUMPTRACE("AquireFence: %d", imported_buffer_->acquire_fence_); + DUMPTRACE("Source crop %s", StringifyRect(source_crop_).c_str()); + DUMPTRACE("Display frame %s", StringifyRect(display_frame_).c_str()); + DUMPTRACE("Surface Damage %s", StringifyRect(surface_damage_).c_str()); + if (imported_buffer_) + DUMPTRACE("AquireFence: %d", imported_buffer_->acquire_fence_); imported_buffer_->buffer_->Dump(); }