1 // Copyright 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "Buffer.h"
16
17 #if GFXSTREAM_ENABLE_HOST_GLES
18 #include "gl/EmulationGl.h"
19 #endif
20
21 #include "vulkan/BufferVk.h"
22 #include "vulkan/VkCommonOperations.h"
23
24 namespace gfxstream {
25
26 using android::base::ManagedDescriptor;
27 using emugl::ABORT_REASON_OTHER;
28 using emugl::FatalError;
29
Buffer(HandleType handle,uint64_t size)30 Buffer::Buffer(HandleType handle, uint64_t size) : mHandle(handle), mSize(size) {}
31
32 /*static*/
create(gl::EmulationGl * emulationGl,vk::VkEmulation * emulationVk,uint64_t size,HandleType handle)33 std::shared_ptr<Buffer> Buffer::create(gl::EmulationGl* emulationGl, vk::VkEmulation* emulationVk,
34 uint64_t size, HandleType handle) {
35 std::shared_ptr<Buffer> buffer(new Buffer(handle, size));
36
37 #if GFXSTREAM_ENABLE_HOST_GLES
38 if (emulationGl) {
39 buffer->mBufferGl = emulationGl->createBuffer(size, handle);
40 if (!buffer->mBufferGl) {
41 ERR("Failed to initialize BufferGl.");
42 return nullptr;
43 }
44 }
45 #endif
46
47 if (emulationVk && emulationVk->live) {
48 const bool vulkanOnly = emulationGl == nullptr;
49
50 buffer->mBufferVk = vk::BufferVk::create(handle, size, vulkanOnly);
51 if (!buffer->mBufferVk) {
52 ERR("Failed to initialize BufferVk.");
53 return nullptr;
54 }
55
56 if (!vulkanOnly) {
57 #if GFXSTREAM_ENABLE_HOST_GLES
58 if (!buffer->mBufferGl) {
59 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Missing BufferGl?";
60 }
61 #endif
62 // TODO: external memory sharing.
63 }
64 }
65
66 return buffer;
67 }
68
69 /*static*/
onLoad(gl::EmulationGl * emulationGl,vk::VkEmulation *,android::base::Stream * stream)70 std::shared_ptr<Buffer> Buffer::onLoad(gl::EmulationGl* emulationGl, vk::VkEmulation*,
71 android::base::Stream* stream) {
72 const auto handle = static_cast<HandleType>(stream->getBe32());
73 const auto size = static_cast<uint64_t>(stream->getBe64());
74
75 std::shared_ptr<Buffer> buffer(new Buffer(handle, size));
76
77 #if GFXSTREAM_ENABLE_HOST_GLES
78 if (emulationGl) {
79 buffer->mBufferGl = emulationGl->loadBuffer(stream);
80 if (!buffer->mBufferGl) {
81 ERR("Failed to load BufferGl.");
82 return nullptr;
83 }
84 }
85 #endif
86
87 buffer->mNeedRestore = true;
88
89 return buffer;
90 }
91
onSave(android::base::Stream * stream)92 void Buffer::onSave(android::base::Stream* stream) {
93 stream->putBe32(mHandle);
94 stream->putBe64(mSize);
95
96 #if GFXSTREAM_ENABLE_HOST_GLES
97 if (mBufferGl) {
98 mBufferGl->onSave(stream);
99 }
100 #endif
101 }
102
restore()103 void Buffer::restore() {}
104
readToBytes(uint64_t offset,uint64_t size,void * outBytes)105 void Buffer::readToBytes(uint64_t offset, uint64_t size, void* outBytes) {
106 touch();
107
108 #if GFXSTREAM_ENABLE_HOST_GLES
109 if (mBufferGl) {
110 mBufferGl->read(offset, size, outBytes);
111 return;
112 }
113 #endif
114
115 if (mBufferVk) {
116 mBufferVk->readToBytes(offset, size, outBytes);
117 return;
118 }
119
120 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No Buffer impl?";
121 }
122
updateFromBytes(uint64_t offset,uint64_t size,const void * bytes)123 bool Buffer::updateFromBytes(uint64_t offset, uint64_t size, const void* bytes) {
124 touch();
125
126 #if GFXSTREAM_ENABLE_HOST_GLES
127 if (mBufferGl) {
128 mBufferGl->subUpdate(offset, size, bytes);
129 return true;
130 }
131 #endif
132
133 if (mBufferVk) {
134 return mBufferVk->updateFromBytes(offset, size, bytes);
135 }
136
137 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No Buffer impl?";
138 return false;
139 }
140
exportBlob()141 std::optional<BlobDescriptorInfo> Buffer::exportBlob() {
142 if (!mBufferVk) {
143 return std::nullopt;
144 }
145
146 return mBufferVk->exportBlob();
147 }
148
149 } // namespace gfxstream
150