| /* |
| * Copyright 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "Layer.h" |
| |
| #include <android-base/unique_fd.h> |
| #include <sync/sync.h> |
| |
| #include <atomic> |
| #include <cmath> |
| |
| namespace aidl::android::hardware::graphics::composer3::impl { |
| namespace { |
| |
| std::atomic<int64_t> sNextId{1}; |
| |
| } // namespace |
| |
| Layer::Layer() : mId(sNextId++) {} |
| |
| HWC3::Error Layer::setCursorPosition(const common::Point& position) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| if (mCompositionType != Composition::CURSOR) { |
| ALOGE("%s: CompositionType not Cursor type", __FUNCTION__); |
| return HWC3::Error::BadLayer; |
| } |
| |
| mCursorPosition = position; |
| return HWC3::Error::None; |
| } |
| |
| common::Point Layer::getCursorPosition() const { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return mCursorPosition; |
| } |
| |
| HWC3::Error Layer::setBuffer(buffer_handle_t buffer, |
| const ndk::ScopedFileDescriptor& fence) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| if (buffer == nullptr) { |
| ALOGE("%s: missing handle", __FUNCTION__); |
| return HWC3::Error::BadParameter; |
| } |
| |
| mBuffer.set(buffer, fence); |
| return HWC3::Error::None; |
| } |
| |
| FencedBuffer& Layer::getBuffer() { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return mBuffer; |
| } |
| |
| buffer_handle_t Layer::waitAndGetBuffer() { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| ::android::base::unique_fd fence = mBuffer.getFence(); |
| if (fence.ok()) { |
| int err = sync_wait(fence.get(), 3000); |
| if (err < 0 && errno == ETIME) { |
| ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__, |
| fence.get()); |
| } |
| } |
| |
| return mBuffer.getBuffer(); |
| } |
| |
| HWC3::Error Layer::setSurfaceDamage( |
| const std::vector<std::optional<common::Rect>>& /*damage*/) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return HWC3::Error::None; |
| } |
| |
| HWC3::Error Layer::setBlendMode(common::BlendMode blendMode) { |
| const auto blendModeString = toString(blendMode); |
| DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, |
| blendModeString.c_str()); |
| |
| mBlendMode = blendMode; |
| return HWC3::Error::None; |
| } |
| |
| common::BlendMode Layer::getBlendMode() const { |
| const auto blendMode = mBlendMode; |
| const auto blendModeString = toString(blendMode); |
| DEBUG_LOG("%s: layer:%" PRId64 " blend mode:%s", __FUNCTION__, mId, |
| blendModeString.c_str()); |
| |
| return blendMode; |
| } |
| |
| HWC3::Error Layer::setColor(Color color) { |
| DEBUG_LOG("%s: layer:%" PRId64 |
| " color-r:%d color-g:%d color-b:%d color-a:%d)", |
| __FUNCTION__, mId, color.r, color.g, color.b, color.a); |
| |
| mColor = color; |
| return HWC3::Error::None; |
| } |
| |
| Color Layer::getColor() const { |
| auto color = mColor; |
| DEBUG_LOG("%s: layer:%" PRId64 |
| " color-r:%d color-g:%d color-b:%d color-a:%d)", |
| __FUNCTION__, mId, color.r, color.g, color.b, color.a); |
| |
| return color; |
| } |
| |
| HWC3::Error Layer::setCompositionType(Composition compositionType) { |
| const auto compositionTypeString = toString(compositionType); |
| DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, |
| compositionTypeString.c_str()); |
| |
| mCompositionType = compositionType; |
| return HWC3::Error::None; |
| } |
| |
| Composition Layer::getCompositionType() const { |
| const auto compositionTypeString = toString(mCompositionType); |
| DEBUG_LOG("%s: layer:%" PRId64 " composition type:%s", __FUNCTION__, mId, |
| compositionTypeString.c_str()); |
| |
| return mCompositionType; |
| } |
| |
| HWC3::Error Layer::setDataspace(common::Dataspace dataspace) { |
| const auto dataspaceString = toString(dataspace); |
| DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, |
| dataspaceString.c_str()); |
| |
| mDataspace = dataspace; |
| return HWC3::Error::None; |
| } |
| |
| common::Dataspace Layer::getDataspace() const { |
| const auto dataspaceString = toString(mDataspace); |
| DEBUG_LOG("%s: layer:%" PRId64 " dataspace:%s", __FUNCTION__, mId, |
| dataspaceString.c_str()); |
| |
| return mDataspace; |
| } |
| |
| HWC3::Error Layer::setDisplayFrame(common::Rect frame) { |
| DEBUG_LOG("%s: layer:%" PRId64 |
| " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", |
| __FUNCTION__, mId, frame.left, frame.top, frame.right, |
| frame.bottom); |
| |
| mDisplayFrame = frame; |
| return HWC3::Error::None; |
| } |
| |
| common::Rect Layer::getDisplayFrame() const { |
| auto frame = mDisplayFrame; |
| DEBUG_LOG("%s: layer:%" PRId64 |
| " display frame rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", |
| __FUNCTION__, mId, frame.left, frame.top, frame.right, |
| frame.bottom); |
| |
| return frame; |
| } |
| |
| HWC3::Error Layer::setPlaneAlpha(float alpha) { |
| DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); |
| |
| mPlaneAlpha = alpha; |
| return HWC3::Error::None; |
| } |
| |
| float Layer::getPlaneAlpha() const { |
| auto alpha = mPlaneAlpha; |
| DEBUG_LOG("%s: layer:%" PRId64 "alpha:%f", __FUNCTION__, mId, alpha); |
| |
| return alpha; |
| } |
| |
| HWC3::Error Layer::setSidebandStream(buffer_handle_t /*stream*/) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return HWC3::Error::None; |
| } |
| |
| HWC3::Error Layer::setSourceCrop(common::FRect crop) { |
| DEBUG_LOG("%s: layer:%" PRId64 |
| "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", |
| __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); |
| |
| mSourceCrop = crop; |
| return HWC3::Error::None; |
| } |
| |
| common::FRect Layer::getSourceCrop() const { |
| common::FRect crop = mSourceCrop; |
| DEBUG_LOG("%s: layer:%" PRId64 |
| "crop rect-left:%f rect-top:%f rect-right:%f rect-bot:%f", |
| __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); |
| |
| return crop; |
| } |
| |
| common::Rect Layer::getSourceCropInt() const { |
| common::Rect crop = {}; |
| crop.left = static_cast<int>(mSourceCrop.left); |
| crop.top = static_cast<int>(mSourceCrop.top); |
| crop.right = static_cast<int>(mSourceCrop.right); |
| crop.bottom = static_cast<int>(mSourceCrop.bottom); |
| DEBUG_LOG("%s: layer:%" PRId64 |
| "crop rect-left:%d rect-top:%d rect-right:%d rect-bot:%d", |
| __FUNCTION__, mId, crop.left, crop.top, crop.right, crop.bottom); |
| |
| return crop; |
| } |
| |
| HWC3::Error Layer::setTransform(common::Transform transform) { |
| const auto transformString = toString(transform); |
| DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, |
| transformString.c_str()); |
| |
| mTransform = transform; |
| return HWC3::Error::None; |
| } |
| |
| common::Transform Layer::getTransform() const { |
| const auto transformString = toString(mTransform); |
| DEBUG_LOG("%s: layer:%" PRId64 " transform:%s", __FUNCTION__, mId, |
| transformString.c_str()); |
| |
| return mTransform; |
| } |
| |
| HWC3::Error Layer::setVisibleRegion( |
| const std::vector<std::optional<common::Rect>>& visible) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| mVisibleRegion.clear(); |
| mVisibleRegion.reserve(visible.size()); |
| for (const auto& rectOption : visible) { |
| if (rectOption) { |
| mVisibleRegion.push_back(*rectOption); |
| } |
| } |
| |
| return HWC3::Error::None; |
| } |
| |
| std::size_t Layer::getNumVisibleRegions() const { |
| const std::size_t num = mVisibleRegion.size(); |
| DEBUG_LOG("%s: layer:%" PRId64 " number of visible regions: %zu", |
| __FUNCTION__, mId, num); |
| |
| return num; |
| } |
| |
| HWC3::Error Layer::setZOrder(int32_t z) { |
| DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, z); |
| |
| mZOrder = z; |
| return HWC3::Error::None; |
| } |
| |
| int32_t Layer::getZOrder() const { |
| DEBUG_LOG("%s: layer:%" PRId64 " z:%d", __FUNCTION__, mId, mZOrder); |
| |
| return mZOrder; |
| } |
| |
| HWC3::Error Layer::setPerFrameMetadata( |
| const std::vector<std::optional<PerFrameMetadata>>& /*perFrameMetadata*/) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return HWC3::Error::None; |
| } |
| |
| HWC3::Error Layer::setColorTransform(const std::vector<float>& colorTransform) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| if (colorTransform.size() < 16) { |
| return HWC3::Error::BadParameter; |
| } |
| |
| mColorTransform.emplace(); |
| std::copy_n(colorTransform.data(), 16, mColorTransform->data()); |
| return HWC3::Error::None; |
| } |
| |
| const std::optional<std::array<float, 16>>& Layer::getColorTransform() const { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return mColorTransform; |
| } |
| |
| HWC3::Error Layer::setBrightness(float brightness) { |
| DEBUG_LOG("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, |
| brightness); |
| |
| if (std::isnan(brightness) || brightness < 0.0f || brightness > 1.0f) { |
| ALOGE("%s: layer:%" PRId64 " brightness:%f", __FUNCTION__, mId, brightness); |
| return HWC3::Error::BadParameter; |
| } |
| |
| mBrightness = brightness; |
| return HWC3::Error::None; |
| } |
| |
| float Layer::getBrightness() const { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return mBrightness; |
| } |
| |
| HWC3::Error Layer::setPerFrameMetadataBlobs( |
| const std::vector< |
| std::optional<PerFrameMetadataBlob>>& /*perFrameMetadata*/) { |
| DEBUG_LOG("%s: layer:%" PRId64, __FUNCTION__, mId); |
| |
| return HWC3::Error::None; |
| } |
| |
| } // namespace aidl::android::hardware::graphics::composer3::impl |