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