1 #include <private/dvr/detached_buffer.h>
2
3 #include <pdx/file_handle.h>
4 #include <ui/DetachedBufferHandle.h>
5
6 #include <poll.h>
7
8 using android::pdx::LocalChannelHandle;
9 using android::pdx::LocalHandle;
10 using android::pdx::Status;
11
12 namespace android {
13 namespace dvr {
14
DetachedBuffer(uint32_t width,uint32_t height,uint32_t layer_count,uint32_t format,uint64_t usage,size_t user_metadata_size)15 DetachedBuffer::DetachedBuffer(uint32_t width, uint32_t height,
16 uint32_t layer_count, uint32_t format,
17 uint64_t usage, size_t user_metadata_size) {
18 ATRACE_NAME("DetachedBuffer::DetachedBuffer");
19 ALOGD_IF(TRACE,
20 "DetachedBuffer::DetachedBuffer: width=%u height=%u layer_count=%u, "
21 "format=%u usage=%" PRIx64 " user_metadata_size=%zu",
22 width, height, layer_count, format, usage, user_metadata_size);
23
24 auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Create>(
25 width, height, layer_count, format, usage, user_metadata_size);
26 if (!status) {
27 ALOGE(
28 "DetachedBuffer::DetachedBuffer: Failed to create detached buffer: %s",
29 status.GetErrorMessage().c_str());
30 client_.Close(-status.error());
31 }
32
33 const int ret = ImportGraphicBuffer();
34 if (ret < 0) {
35 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import buffer: %s",
36 strerror(-ret));
37 client_.Close(ret);
38 }
39 }
40
DetachedBuffer(LocalChannelHandle channel_handle)41 DetachedBuffer::DetachedBuffer(LocalChannelHandle channel_handle)
42 : client_(std::move(channel_handle)) {
43 const int ret = ImportGraphicBuffer();
44 if (ret < 0) {
45 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import buffer: %s",
46 strerror(-ret));
47 client_.Close(ret);
48 }
49 }
50
ImportGraphicBuffer()51 int DetachedBuffer::ImportGraphicBuffer() {
52 ATRACE_NAME("DetachedBuffer::DetachedBuffer");
53
54 auto status = client_.InvokeRemoteMethod<DetachedBufferRPC::Import>();
55 if (!status) {
56 ALOGE("DetachedBuffer::DetachedBuffer: Failed to import GraphicBuffer: %s",
57 status.GetErrorMessage().c_str());
58 return -status.error();
59 }
60
61 BufferDescription<LocalHandle> buffer_desc = status.take();
62 if (buffer_desc.id() < 0) {
63 ALOGE("DetachedBuffer::DetachedBuffer: Received an invalid id!");
64 return -EIO;
65 }
66
67 // Stash the buffer id to replace the value in id_.
68 const int buffer_id = buffer_desc.id();
69
70 // Import the buffer.
71 IonBuffer ion_buffer;
72 ALOGD_IF(TRACE, "DetachedBuffer::DetachedBuffer: id=%d.", buffer_id);
73
74 if (const int ret = buffer_desc.ImportBuffer(&ion_buffer)) {
75 ALOGE("Failed to import GraphicBuffer, error=%d", ret);
76 return ret;
77 }
78
79 // If all imports succeed, replace the previous buffer and id.
80 id_ = buffer_id;
81 buffer_ = std::move(ion_buffer);
82 return 0;
83 }
84
Poll(int timeout_ms)85 int DetachedBuffer::Poll(int timeout_ms) {
86 ATRACE_NAME("DetachedBuffer::Poll");
87 pollfd p = {client_.event_fd(), POLLIN, 0};
88 return poll(&p, 1, timeout_ms);
89 }
90
Promote()91 Status<LocalChannelHandle> DetachedBuffer::Promote() {
92 ATRACE_NAME("DetachedBuffer::Promote");
93 ALOGD_IF(TRACE, "DetachedBuffer::Promote: id=%d.", id_);
94
95 auto status_or_handle =
96 client_.InvokeRemoteMethod<DetachedBufferRPC::Promote>();
97 if (status_or_handle.ok()) {
98 // Invalidate the buffer.
99 buffer_ = {};
100 } else {
101 ALOGE("DetachedBuffer::Promote: Failed to promote buffer (id=%d): %s.", id_,
102 status_or_handle.GetErrorMessage().c_str());
103 }
104 return status_or_handle;
105 }
106
TakeGraphicBuffer()107 sp<GraphicBuffer> DetachedBuffer::TakeGraphicBuffer() {
108 if (!client_.IsValid() || !buffer_.buffer()) {
109 ALOGE("DetachedBuffer::TakeGraphicBuffer: Invalid buffer.");
110 return nullptr;
111 }
112
113 // Technically this should never happen.
114 LOG_FATAL_IF(
115 buffer_.buffer()->isDetachedBuffer(),
116 "DetachedBuffer::TakeGraphicBuffer: GraphicBuffer is already detached.");
117
118 sp<GraphicBuffer> buffer = std::move(buffer_.buffer());
119 buffer->setDetachedBufferHandle(
120 DetachedBufferHandle::Create(client_.TakeChannelHandle()));
121 return buffer;
122 }
123
124 } // namespace dvr
125 } // namespace android
126