1 // Copyright 2024 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 "gfxstream/guest/RenderControl.h"
16
17 #include <vector>
18
19 #include "HostConnection.h"
20
21 namespace {
22
23 typedef struct compose_layer {
24 uint32_t cbHandle;
25 hwc2_composition_t composeMode;
26 hwc_rect_t displayFrame;
27 hwc_frect_t crop;
28 int32_t blendMode;
29 float alpha;
30 hwc_color_t color;
31 hwc_transform_t transform;
32 } ComposeLayer;
33
34 typedef struct compose_device {
35 uint32_t version;
36 uint32_t targetHandle;
37 uint32_t numLayers;
38 struct compose_layer layer[0];
39 } ComposeDevice;
40
41 typedef struct compose_device_v2 {
42 uint32_t version;
43 uint32_t displayId;
44 uint32_t targetHandle;
45 uint32_t numLayers;
46 struct compose_layer layer[0];
47 } ComposeDevice_v2;
48
49 class RenderControlDeviceImpl {
50 public:
RenderControlDeviceImpl()51 RenderControlDeviceImpl() : mHostConnection(HostConnection::createUnique(kCapsetNone)) {}
52
53 RenderControlDeviceImpl(const RenderControlDeviceImpl& rhs) = delete;
54 RenderControlDeviceImpl& operator=(const RenderControlDeviceImpl& rhs) = delete;
55
56 RenderControlDeviceImpl(RenderControlDeviceImpl&& rhs) = delete;
57 RenderControlDeviceImpl& operator=(RenderControlDeviceImpl&& rhs) = delete;
58
DoCompose(std::vector<uint8_t> & bytes)59 int DoCompose(std::vector<uint8_t>& bytes) {
60 if (!mHostConnection) {
61 ALOGE("RenderControlDevice missing HostConnection.");
62 return -1;
63 }
64
65 auto* rc = mHostConnection->rcEncoder();
66 if (!rc) {
67 ALOGE("RenderControlDevice missing rcEncoder.");
68 return -1;
69 }
70
71 mHostConnection->lock();
72 rc->rcCompose(rc, bytes.size(), bytes.data());
73 mHostConnection->unlock();
74 return 0;
75 }
76
77 private:
78 std::unique_ptr<HostConnection> mHostConnection;
79 };
80
ToHandle(RenderControlDeviceImpl * device)81 RenderControlDevice* ToHandle(RenderControlDeviceImpl* device) {
82 return reinterpret_cast<RenderControlDevice*>(device);
83 }
84
ToImpl(RenderControlDevice * device)85 RenderControlDeviceImpl* ToImpl(RenderControlDevice* device) {
86 return reinterpret_cast<RenderControlDeviceImpl*>(device);
87 }
88
89 } // namespace
90
rcCreateDevice()91 extern "C" __attribute__((visibility("default"))) RenderControlDevice* rcCreateDevice() {
92 return ToHandle(new RenderControlDeviceImpl());
93 }
94
rcDestroyDevice(RenderControlDevice * pDevice)95 extern "C" __attribute__((visibility("default"))) void rcDestroyDevice(
96 RenderControlDevice* pDevice) {
97 if (pDevice != nullptr) {
98 delete ToImpl(pDevice);
99 }
100 }
101
rcCompose(RenderControlDevice * deviceHandle,const RenderControlComposition * pComposition,uint32_t compositionLayerCount,const RenderControlCompositionLayer * pCompositionLayers)102 extern "C" __attribute__((visibility("default"))) int rcCompose(
103 RenderControlDevice* deviceHandle, const RenderControlComposition* pComposition,
104 uint32_t compositionLayerCount, const RenderControlCompositionLayer* pCompositionLayers) {
105 const size_t bytesNeeded =
106 sizeof(ComposeDevice_v2) + (sizeof(ComposeLayer) * compositionLayerCount);
107 std::vector<uint8_t> bytes(bytesNeeded);
108
109 auto* composeDevice = reinterpret_cast<ComposeDevice_v2*>(bytes.data());
110 auto* composeLayers = composeDevice->layer;
111
112 composeDevice->version = 2;
113 composeDevice->displayId = 0;
114 composeDevice->targetHandle = pComposition->compositionResultColorBufferHandle;
115 composeDevice->numLayers = compositionLayerCount;
116
117 for (uint32_t i = 0; i < compositionLayerCount; i++) {
118 auto& requestLayer = pCompositionLayers[i];
119 auto& composeLayer = composeLayers[i];
120 composeLayer.cbHandle = requestLayer.colorBufferHandle;
121 composeLayer.composeMode = requestLayer.composeMode;
122 composeLayer.displayFrame = requestLayer.displayFrame;
123 composeLayer.crop = requestLayer.crop;
124 composeLayer.blendMode = requestLayer.blendMode;
125 composeLayer.alpha = requestLayer.alpha;
126 composeLayer.color = requestLayer.color;
127 composeLayer.transform = requestLayer.transform;
128 }
129
130 RenderControlDeviceImpl* device = ToImpl(deviceHandle);
131 return device->DoCompose(bytes);
132 }
133