diff options
author | Sean Paul <seanpaul@chromium.org> | 2019-04-02 16:57:20 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2019-06-11 09:38:11 -0400 |
commit | 27cd4805010184f0e9faf712dd0980e8700c26b9 (patch) | |
tree | 612e46bdbc17a10f1556325241553de299a8e2a3 /utils | |
parent | 17d3c8bba62abb1c646c2c2133d1d66b0b457be9 (diff) |
drm_hwcomposer: Organize files into subdirs
This is way overdue
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Change-Id: I1bcbd8fdb0bb03feafd76bc41f6f11c03cdf9c25
Diffstat (limited to 'utils')
-rw-r--r-- | utils/autolock.cpp | 56 | ||||
-rw-r--r-- | utils/hwcutils.cpp | 171 | ||||
-rw-r--r-- | utils/worker.cpp | 94 |
3 files changed, 321 insertions, 0 deletions
diff --git a/utils/autolock.cpp b/utils/autolock.cpp new file mode 100644 index 0000000..4e9552a --- /dev/null +++ b/utils/autolock.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 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. + */ + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS +#define LOG_TAG "hwc-drm-auto-lock" + +#include "autolock.h" + +#include <errno.h> +#include <pthread.h> + +#include <log/log.h> + +namespace android { + +int AutoLock::Lock() { + if (locked_) { + ALOGE("Invalid attempt to double lock AutoLock %s", name_); + return -EINVAL; + } + int ret = pthread_mutex_lock(mutex_); + if (ret) { + ALOGE("Failed to acquire %s lock %d", name_, ret); + return ret; + } + locked_ = true; + return 0; +} + +int AutoLock::Unlock() { + if (!locked_) { + ALOGE("Invalid attempt to unlock unlocked AutoLock %s", name_); + return -EINVAL; + } + int ret = pthread_mutex_unlock(mutex_); + if (ret) { + ALOGE("Failed to release %s lock %d", name_, ret); + return ret; + } + locked_ = false; + return 0; +} +} // namespace android diff --git a/utils/hwcutils.cpp b/utils/hwcutils.cpp new file mode 100644 index 0000000..87e3c42 --- /dev/null +++ b/utils/hwcutils.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2016 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. + */ + +#define ATRACE_TAG ATRACE_TAG_GRAPHICS +#define LOG_TAG "hwc-drm-utils" + +#include "drmhwcomposer.h" +#include "platform.h" + +#include <log/log.h> +#include <ui/GraphicBufferMapper.h> + +#define UNUSED(x) (void)(x) + +namespace android { + +const hwc_drm_bo *DrmHwcBuffer::operator->() const { + if (importer_ == NULL) { + ALOGE("Access of non-existent BO"); + exit(1); + return NULL; + } + return &bo_; +} + +void DrmHwcBuffer::Clear() { + if (importer_ != NULL) { + importer_->ReleaseBuffer(&bo_); + importer_ = NULL; + } +} + +int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) { + hwc_drm_bo tmp_bo; + + int ret = importer->ImportBuffer(handle, &tmp_bo); + if (ret) + return ret; + + if (importer_ != NULL) { + importer_->ReleaseBuffer(&bo_); + } + + importer_ = importer; + + bo_ = tmp_bo; + + return 0; +} + +int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle, int width, + int height, int layerCount, int format, + int usage, int stride) { + native_handle_t *handle_copy; + GraphicBufferMapper &gm(GraphicBufferMapper::get()); + int ret; + +#ifdef HWC2_USE_OLD_GB_IMPORT + UNUSED(width); + UNUSED(height); + UNUSED(layerCount); + UNUSED(format); + UNUSED(usage); + UNUSED(stride); + ret = gm.importBuffer(handle, const_cast<buffer_handle_t *>(&handle_copy)); +#else + ret = gm.importBuffer(handle, width, height, layerCount, format, usage, + stride, const_cast<buffer_handle_t *>(&handle_copy)); +#endif + if (ret) { + ALOGE("Failed to import buffer handle %d", ret); + return ret; + } + + Clear(); + + handle_ = handle_copy; + + return 0; +} + +DrmHwcNativeHandle::~DrmHwcNativeHandle() { + Clear(); +} + +void DrmHwcNativeHandle::Clear() { + if (handle_ != NULL) { + GraphicBufferMapper &gm(GraphicBufferMapper::get()); + int ret = gm.freeBuffer(handle_); + if (ret) { + ALOGE("Failed to free buffer handle %d", ret); + } + handle_ = NULL; + } +} + +int DrmHwcLayer::ImportBuffer(Importer *importer) { + int ret = buffer.ImportBuffer(sf_handle, importer); + if (ret) + return ret; + + const hwc_drm_bo *bo = buffer.operator->(); + + unsigned int layer_count; + for (layer_count = 0; layer_count < HWC_DRM_BO_MAX_PLANES; ++layer_count) + if (bo->gem_handles[layer_count] == 0) + break; + + ret = handle.CopyBufferHandle(sf_handle, bo->width, bo->height, layer_count, + bo->hal_format, bo->usage, bo->pixel_stride); + if (ret) + return ret; + + gralloc_buffer_usage = bo->usage; + + return 0; +} + +int DrmHwcLayer::InitFromDrmHwcLayer(DrmHwcLayer *src_layer, + Importer *importer) { + blending = src_layer->blending; + sf_handle = src_layer->sf_handle; + acquire_fence = -1; + display_frame = src_layer->display_frame; + alpha = src_layer->alpha; + source_crop = src_layer->source_crop; + transform = src_layer->transform; + return ImportBuffer(importer); +} + +void DrmHwcLayer::SetSourceCrop(hwc_frect_t const &crop) { + source_crop = crop; +} + +void DrmHwcLayer::SetDisplayFrame(hwc_rect_t const &frame) { + display_frame = frame; +} + +void DrmHwcLayer::SetTransform(int32_t sf_transform) { + transform = 0; + // 270* and 180* cannot be combined with flips. More specifically, they + // already contain both horizontal and vertical flips, so those fields are + // redundant in this case. 90* rotation can be combined with either horizontal + // flip or vertical flip, so treat it differently + if (sf_transform == HWC_TRANSFORM_ROT_270) { + transform = DrmHwcTransform::kRotate270; + } else if (sf_transform == HWC_TRANSFORM_ROT_180) { + transform = DrmHwcTransform::kRotate180; + } else { + if (sf_transform & HWC_TRANSFORM_FLIP_H) + transform |= DrmHwcTransform::kFlipH; + if (sf_transform & HWC_TRANSFORM_FLIP_V) + transform |= DrmHwcTransform::kFlipV; + if (sf_transform & HWC_TRANSFORM_ROT_90) + transform |= DrmHwcTransform::kRotate90; + } +} +} // namespace android diff --git a/utils/worker.cpp b/utils/worker.cpp new file mode 100644 index 0000000..0dceb16 --- /dev/null +++ b/utils/worker.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015-2016 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 "worker.h" + +#include <sys/prctl.h> +#include <sys/resource.h> + +namespace android { + +Worker::Worker(const char *name, int priority) + : name_(name), priority_(priority), exit_(false), initialized_(false) { +} + +Worker::~Worker() { + Exit(); +} + +int Worker::InitWorker() { + std::lock_guard<std::mutex> lk(mutex_); + if (initialized()) + return -EALREADY; + + thread_ = std::unique_ptr<std::thread>( + new std::thread(&Worker::InternalRoutine, this)); + initialized_ = true; + exit_ = false; + + return 0; +} + +void Worker::Exit() { + std::unique_lock<std::mutex> lk(mutex_); + exit_ = true; + if (initialized()) { + lk.unlock(); + cond_.notify_all(); + thread_->join(); + initialized_ = false; + } +} + +int Worker::WaitForSignalOrExitLocked(int64_t max_nanoseconds) { + int ret = 0; + if (should_exit()) + return -EINTR; + + std::unique_lock<std::mutex> lk(mutex_, std::adopt_lock); + if (max_nanoseconds < 0) { + cond_.wait(lk); + } else if (std::cv_status::timeout == + cond_.wait_for(lk, std::chrono::nanoseconds(max_nanoseconds))) { + ret = -ETIMEDOUT; + } + + // exit takes precedence on timeout + if (should_exit()) + ret = -EINTR; + + // release leaves mutex locked when going out of scope + lk.release(); + + return ret; +} + +void Worker::InternalRoutine() { + setpriority(PRIO_PROCESS, 0, priority_); + prctl(PR_SET_NAME, name_.c_str()); + + std::unique_lock<std::mutex> lk(mutex_, std::defer_lock); + + while (true) { + lk.lock(); + if (should_exit()) + return; + lk.unlock(); + + Routine(); + } +} +} // namespace android |