blob: 5af0e4f857db72d31ccf093840dfb11bbbde4ec5 [file] [log] [blame]
Alec Mouri16a99402019-07-29 16:37:30 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19#include <pthread.h>
20
21#include <processgroup/sched_policy.h>
22#include <utils/Trace.h>
23#include "GLESRenderEngine.h"
24#include "ImageManager.h"
25
26namespace android {
27namespace renderengine {
28namespace gl {
29
30ImageManager::ImageManager(GLESRenderEngine* engine) : mEngine(engine) {
31 pthread_setname_np(mThread.native_handle(), "ImageManager");
32 // Use SCHED_FIFO to minimize jitter
33 struct sched_param param = {0};
34 param.sched_priority = 2;
35 if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {
36 ALOGE("Couldn't set SCHED_FIFO for ImageManager");
37 }
38}
39
40ImageManager::~ImageManager() {
41 {
42 std::lock_guard<std::mutex> lock(mMutex);
43 mRunning = false;
44 }
45 mCondition.notify_all();
46 if (mThread.joinable()) {
47 mThread.join();
48 }
49}
50
51void ImageManager::cacheAsync(const sp<GraphicBuffer>& buffer,
52 const std::shared_ptr<Barrier>& barrier) {
53 if (buffer == nullptr) {
54 {
55 std::lock_guard<std::mutex> lock(barrier->mutex);
56 barrier->isOpen = true;
57 barrier->result = BAD_VALUE;
58 }
59 barrier->condition.notify_one();
60 return;
61 }
62 ATRACE_CALL();
63 QueueEntry entry = {QueueEntry::Operation::Insert, buffer, buffer->getId(), barrier};
64 queueOperation(std::move(entry));
65}
66
67status_t ImageManager::cache(const sp<GraphicBuffer>& buffer) {
68 ATRACE_CALL();
69 auto barrier = std::make_shared<Barrier>();
70 cacheAsync(buffer, barrier);
71 std::lock_guard<std::mutex> lock(barrier->mutex);
72 barrier->condition.wait(barrier->mutex,
73 [&]() REQUIRES(barrier->mutex) { return barrier->isOpen; });
74 return barrier->result;
75}
76
77void ImageManager::releaseAsync(uint64_t bufferId, const std::shared_ptr<Barrier>& barrier) {
78 ATRACE_CALL();
79 QueueEntry entry = {QueueEntry::Operation::Delete, nullptr, bufferId, barrier};
80 queueOperation(std::move(entry));
81}
82
83void ImageManager::queueOperation(const QueueEntry&& entry) {
84 {
85 std::lock_guard<std::mutex> lock(mMutex);
86 mQueue.emplace(entry);
87 ATRACE_INT("ImageManagerQueueDepth", mQueue.size());
88 }
89 mCondition.notify_one();
90}
91
92void ImageManager::threadMain() {
93 set_sched_policy(0, SP_FOREGROUND);
94 bool run;
95 {
96 std::lock_guard<std::mutex> lock(mMutex);
97 run = mRunning;
98 }
99 while (run) {
100 QueueEntry entry;
101 {
102 std::lock_guard<std::mutex> lock(mMutex);
103 mCondition.wait(mMutex,
104 [&]() REQUIRES(mMutex) { return !mQueue.empty() || !mRunning; });
105 run = mRunning;
106
107 if (!mRunning) {
108 // if mRunning is false, then ImageManager is being destroyed, so
109 // bail out now.
110 break;
111 }
112
113 entry = mQueue.front();
114 mQueue.pop();
115 ATRACE_INT("ImageManagerQueueDepth", mQueue.size());
116 }
117
118 status_t result = NO_ERROR;
119 switch (entry.op) {
120 case QueueEntry::Operation::Delete:
121 mEngine->unbindExternalTextureBufferInternal(entry.bufferId);
122 break;
123 case QueueEntry::Operation::Insert:
124 result = mEngine->cacheExternalTextureBufferInternal(entry.buffer);
125 break;
126 }
127 if (entry.barrier != nullptr) {
128 {
129 std::lock_guard<std::mutex> entryLock(entry.barrier->mutex);
130 entry.barrier->result = result;
131 entry.barrier->isOpen = true;
132 }
133 entry.barrier->condition.notify_one();
134 }
135 }
136}
137
138} // namespace gl
139} // namespace renderengine
140} // namespace android