summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2019-04-02 16:57:20 -0400
committerSean Paul <seanpaul@chromium.org>2019-06-11 09:38:11 -0400
commit27cd4805010184f0e9faf712dd0980e8700c26b9 (patch)
tree612e46bdbc17a10f1556325241553de299a8e2a3 /utils
parent17d3c8bba62abb1c646c2c2133d1d66b0b457be9 (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.cpp56
-rw-r--r--utils/hwcutils.cpp171
-rw-r--r--utils/worker.cpp94
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