blob: 9293711d0e693b2a03fc75331d78bee5da652fcd [file] [log] [blame]
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -07001/*
2 * Copyright (C) 2018 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// We would eliminate the clang warnings introduced by libdpx.
18// TODO(b/112338294): Remove those once BufferHub moved to use Binder
19#pragma clang diagnostic push
20#pragma clang diagnostic ignored "-Wconversion"
21#pragma clang diagnostic ignored "-Wdouble-promotion"
22#pragma clang diagnostic ignored "-Wgnu-case-range"
23#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
24#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
25#pragma clang diagnostic ignored "-Wnested-anon-types"
26#pragma clang diagnostic ignored "-Wpacked"
27#pragma clang diagnostic ignored "-Wshadow"
28#pragma clang diagnostic ignored "-Wsign-conversion"
29#pragma clang diagnostic ignored "-Wswitch-enum"
30#pragma clang diagnostic ignored "-Wundefined-func-template"
31#pragma clang diagnostic ignored "-Wunused-template"
32#pragma clang diagnostic ignored "-Wweak-vtables"
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070033#include <pdx/default_transport/client_channel.h>
34#include <pdx/default_transport/client_channel_factory.h>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070035#include <pdx/file_handle.h>
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070036#include <private/dvr/bufferhub_rpc.h>
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -070037#pragma clang diagnostic pop
38
39#include <ui/BufferHubBuffer.h>
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070040#include <ui/DetachedBufferHandle.h>
41
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070042#include <poll.h>
43
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -070044using android::dvr::BufferHubMetadata;
45using android::dvr::BufferTraits;
46using android::dvr::DetachedBufferRPC;
47using android::dvr::NativeHandleWrapper;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070048using android::pdx::LocalChannelHandle;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070049using android::pdx::LocalHandle;
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -070050using android::pdx::Status;
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070051using android::pdx::default_transport::ClientChannel;
52using android::pdx::default_transport::ClientChannelFactory;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070053
54namespace android {
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070055
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070056namespace {
57
58// TODO(b/112338294): Remove this string literal after refactoring BufferHub
59// to use Binder.
60static constexpr char kBufferHubClientPath[] = "system/buffer_hub/client";
61
62} // namespace
63
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070064BufferHubClient::BufferHubClient()
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -070065 : Client(ClientChannelFactory::Create(kBufferHubClientPath)) {}
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070066
67BufferHubClient::BufferHubClient(LocalChannelHandle channel_handle)
68 : Client(ClientChannel::Create(std::move(channel_handle))) {}
69
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -070070BufferHubClient::~BufferHubClient() {}
71
Jiwen 'Steve' Cai088b3b62018-10-03 18:49:07 -070072bool BufferHubClient::IsValid() const {
73 return IsConnected() && GetChannelHandle().valid();
74}
75
76LocalChannelHandle BufferHubClient::TakeChannelHandle() {
77 if (IsConnected()) {
78 return std::move(GetChannelHandle());
79 } else {
80 return {};
81 }
82}
83
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070084DetachedBuffer::DetachedBuffer(uint32_t width, uint32_t height,
85 uint32_t layer_count, uint32_t format,
86 uint64_t usage, size_t user_metadata_size) {
87 ATRACE_NAME("DetachedBuffer::DetachedBuffer");
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -070088 ALOGD("DetachedBuffer::DetachedBuffer: width=%u height=%u layer_count=%u, format=%u "
89 "usage=%" PRIx64 " user_metadata_size=%zu",
90 width, height, layer_count, format, usage, user_metadata_size);
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -070091
92 auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Create>(
93 width, height, layer_count, format, usage, user_metadata_size);
94 if (!status) {
95 ALOGE(
96 "DetachedBuffer::DetachedBuffer: Failed to create detached buffer: %s",
97 status.GetErrorMessage().c_str());
98 client_.Close(-status.error());
99 }
100
101 const int ret = ImportGraphicBuffer();
102 if (ret < 0) {
103 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import buffer: %s",
104 strerror(-ret));
105 client_.Close(ret);
106 }
107}
108
109DetachedBuffer::DetachedBuffer(LocalChannelHandle channel_handle)
110 : client_(std::move(channel_handle)) {
111 const int ret = ImportGraphicBuffer();
112 if (ret < 0) {
113 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import buffer: %s",
114 strerror(-ret));
115 client_.Close(ret);
116 }
117}
118
119int DetachedBuffer::ImportGraphicBuffer() {
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700120 ATRACE_NAME("DetachedBuffer::ImportGraphicBuffer");
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700121
122 auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Import>();
123 if (!status) {
124 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import GraphicBuffer: %s",
125 status.GetErrorMessage().c_str());
126 return -status.error();
127 }
128
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700129 BufferTraits<LocalHandle> buffer_traits = status.take();
130 if (buffer_traits.id() < 0) {
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700131 ALOGE("DetachedBuffer::DetachedBuffer: Received an invalid id!");
132 return -EIO;
133 }
134
135 // Stash the buffer id to replace the value in id_.
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700136 const int buffer_id = buffer_traits.id();
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700137
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700138 // Import the metadata.
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700139 metadata_ = BufferHubMetadata::Import(buffer_traits.take_metadata_handle());
140
141 if (!metadata_.IsValid()) {
142 ALOGE("DetachedBuffer::ImportGraphicBuffer: invalid metadata.");
143 return -ENOMEM;
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700144 }
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700145
146 if (metadata_.metadata_size() != buffer_traits.metadata_size()) {
147 ALOGE(
148 "DetachedBuffer::ImportGraphicBuffer: metadata buffer too small: "
149 "%zu, expected: %" PRIu64 ".",
150 metadata_.metadata_size(), buffer_traits.metadata_size());
151 return -ENOMEM;
152 }
153
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -0700154 size_t metadata_buf_size = static_cast<size_t>(buffer_traits.metadata_size());
155 if (metadata_buf_size < dvr::BufferHubDefs::kMetadataHeaderSize) {
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700156 ALOGE("DetachedBuffer::ImportGraphicBuffer: metadata too small: %zu",
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700157 metadata_buf_size);
158 return -EINVAL;
159 }
160
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700161 // Import the buffer: We only need to hold on the native_handle_t here so that
162 // GraphicBuffer instance can be created in future.
163 buffer_handle_ = buffer_traits.take_buffer_handle();
164
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700165 // If all imports succeed, replace the previous buffer and id.
166 id_ = buffer_id;
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700167 buffer_state_bit_ = buffer_traits.buffer_state_bit();
Jiwen 'Steve' Caif326fce2018-08-06 17:36:50 -0700168
169 // TODO(b/112012161) Set up shared fences.
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -0700170 ALOGD("DetachedBuffer::ImportGraphicBuffer: id=%d, buffer_state=%" PRIx64 ".", id(),
171 metadata_.metadata_header()->buffer_state.load(std::memory_order_acquire));
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700172 return 0;
173}
174
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700175int DetachedBuffer::Poll(int timeout_ms) {
176 ATRACE_NAME("DetachedBuffer::Poll");
177 pollfd p = {client_.event_fd(), POLLIN, 0};
178 return poll(&p, 1, timeout_ms);
179}
180
181Status<LocalChannelHandle> DetachedBuffer::Promote() {
Fan Xuddb90db2018-10-03 10:09:14 -0700182 // TODO(b/112338294) remove after migrate producer buffer to binder
183 ALOGW("DetachedBuffer::Promote: not supported operation during migration");
184 return {};
185
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700186 ATRACE_NAME("DetachedBuffer::Promote");
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -0700187 ALOGD("DetachedBuffer::Promote: id=%d.", id_);
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700188
189 auto status_or_handle =
190 client_.InvokeRemoteMethod<DetachedBufferRPC::Promote>();
191 if (status_or_handle.ok()) {
192 // Invalidate the buffer.
Jiwen 'Steve' Cai9004b8c2018-10-03 18:52:23 -0700193 buffer_handle_ = {};
Jiwen 'Steve' Cai0728fa92018-04-24 19:03:14 -0700194 } else {
195 ALOGE("DetachedBuffer::Promote: Failed to promote buffer (id=%d): %s.", id_,
196 status_or_handle.GetErrorMessage().c_str());
197 }
198 return status_or_handle;
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700199}
200
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700201Status<LocalChannelHandle> DetachedBuffer::Duplicate() {
202 ATRACE_NAME("DetachedBuffer::Duplicate");
Jiwen 'Steve' Cai8f51ec62018-08-07 21:50:51 -0700203 ALOGD("DetachedBuffer::Duplicate: id=%d.", id_);
Jiwen 'Steve' Cai2e06c1c2018-07-30 21:35:32 -0700204
205 auto status_or_handle =
206 client_.InvokeRemoteMethod<DetachedBufferRPC::Duplicate>();
207
208 if (!status_or_handle.ok()) {
209 ALOGE("DetachedBuffer::Duplicate: Failed to duplicate buffer (id=%d): %s.",
210 id_, status_or_handle.GetErrorMessage().c_str());
211 }
212 return status_or_handle;
213}
214
Jiwen 'Steve' Caia8049a22018-03-28 15:14:02 -0700215} // namespace android