OSDN Git Service

bd6fe67b2cf4e6638f23058d7167c65109e09b70
[android-x86/external-drmfb-composer.git] / DrmComposer.cpp
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2019 Stephan Gerhold
3
4 #define LOG_TAG "drmfb-composer"
5
6 #include <numeric>
7 #include <android-base/logging.h>
8 #include <composer-hal/2.1/Composer.h>
9 #include <sync/sync.h>
10 #include "DrmComposer.h"
11 #include "DrmComposerHal.h"
12
13 namespace android {
14 namespace hardware {
15 namespace graphics {
16 namespace composer {
17 namespace V2_1 {
18 namespace drmfb {
19
20 android::sp<IComposer> createDrmComposer() {
21     auto device = std::make_unique<DrmDevice>();
22     if (!device->initialize()) {
23         return {};
24     }
25
26     return new hal::Composer{std::make_unique<DrmComposerHal>(std::move(device))};
27 }
28
29 DrmComposerHal::DrmComposerHal(std::unique_ptr<DrmDevice> device)
30     : mDevice(std::move(device)) {}
31
32 bool DrmComposerHal::hasCapability(hwc2_capability_t capability) {
33     // TODO: Is there a way to implement them without atomic modesetting?
34     return static_cast<IComposer::Capability>(capability)
35                 == IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE;
36 }
37
38 std::string DrmComposerHal::dumpDebugInfo() {
39     return ""; // TODO
40 }
41
42 void DrmComposerHal::registerEventCallback(EventCallback* callback) {
43     mCallback = callback;
44     mDevice->enable(this);
45 }
46
47 void DrmComposerHal::unregisterEventCallback() {
48     LOG(INFO) << "Client destroyed, disabling displays";
49     mDevice->disable();
50
51     mCallback = nullptr;
52     mLayers.clear();
53     mNextLayer = 0;
54 }
55
56 void DrmComposerHal::onHotplug(const DrmDisplay& display, bool connected) {
57     mCallback->onHotplug(display.id(),
58         connected ? IComposerCallback::Connection::CONNECTED
59             : IComposerCallback::Connection::DISCONNECTED);
60 }
61
62 void DrmComposerHal::onVsync(const DrmDisplay& display, int64_t timestamp) {
63     mCallback->onVsync(display.id(), timestamp);
64 }
65
66 uint32_t DrmComposerHal::getMaxVirtualDisplayCount() {
67     return 0; // Not supported
68 }
69
70 Error DrmComposerHal::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
71         PixelFormat* /*format*/, Display* /*outDisplayId*/) {
72     return Error::NO_RESOURCES;
73 }
74
75 Error DrmComposerHal::destroyVirtualDisplay(Display /*displayId*/) {
76     return Error::BAD_DISPLAY;
77 }
78
79 Error DrmComposerHal::createLayer(Display displayId, Layer* outLayer) {
80     if (!mDevice->getConnectedDisplay(displayId))
81         return Error::BAD_DISPLAY;
82
83     *outLayer = mNextLayer++;
84     mLayers.emplace(*outLayer, displayId);
85     return Error::NONE;
86 }
87
88 Error DrmComposerHal::destroyLayer(Display displayId, Layer layer) {
89     auto i = mLayers.find(layer);
90     if (i == mLayers.end())
91         return Error::BAD_LAYER;
92     if (displayId != i->second.displayId)
93         return Error::BAD_DISPLAY;
94
95     mLayers.erase(i);
96     return Error::NONE;
97 }
98
99
100 Error DrmComposerHal::getActiveConfig(Display displayId, Config* outConfig) {
101     auto display = mDevice->getConnectedDisplay(displayId);
102     if (!display)
103         return Error::BAD_DISPLAY;
104
105     *outConfig = display->currentMode();
106     return Error::NONE;
107 }
108
109 Error DrmComposerHal::getClientTargetSupport(Display displayId,
110         uint32_t width, uint32_t height, PixelFormat format, Dataspace dataspace) {
111     auto display = mDevice->getConnectedDisplay(displayId);
112     if (!display)
113         return Error::BAD_DISPLAY;
114
115     return width == static_cast<uint32_t>(display->width(display->currentMode()))
116         && height == static_cast<uint32_t>(display->height(display->currentMode()))
117         && format == PixelFormat::RGBA_8888 && dataspace == Dataspace::UNKNOWN
118             ? Error::NONE : Error::UNSUPPORTED;
119 }
120
121 Error DrmComposerHal::getColorModes(Display displayId, hidl_vec<ColorMode>* outModes) {
122     if (!mDevice->getConnectedDisplay(displayId))
123         return Error::BAD_DISPLAY;
124
125     *outModes = hidl_vec<ColorMode>{ColorMode::NATIVE};
126     return Error::NONE;
127 }
128
129 Error DrmComposerHal::getDisplayAttribute(Display displayId, Config config,
130         IComposerClient::Attribute attribute, int32_t* outValue) {
131     auto display = mDevice->getConnectedDisplay(displayId);
132     if (!display)
133         return Error::BAD_DISPLAY;
134
135     switch (attribute) {
136     case IComposerClient::Attribute::WIDTH:
137         *outValue = display->width(config);
138         break;
139     case IComposerClient::Attribute::HEIGHT:
140         *outValue = display->height(config);
141         break;
142     case IComposerClient::Attribute::VSYNC_PERIOD:
143         *outValue = display->vsyncPeriod(config);
144         break;
145     case IComposerClient::Attribute::DPI_X:
146         *outValue = display->dpiX(config);
147         break;
148     case IComposerClient::Attribute::DPI_Y:
149         *outValue = display->dpiY(config);
150         break;
151     default:
152         return Error::BAD_PARAMETER;
153     }
154
155     switch (*outValue) {
156     case -1:
157         return Error::BAD_CONFIG;
158     case 0:
159         return Error::UNSUPPORTED;
160     default:
161         return Error::NONE;
162     }
163 }
164
165 Error DrmComposerHal::getDisplayConfigs(Display displayId, hidl_vec<Config>* outConfigs) {
166     auto display = mDevice->getConnectedDisplay(displayId);
167     if (!display)
168         return Error::BAD_DISPLAY;
169
170     outConfigs->resize(display->modeCount());
171     std::iota(outConfigs->begin(), outConfigs->end(), 0);
172     return Error::NONE;
173 }
174
175 Error DrmComposerHal::getDisplayName(Display displayId, hidl_string* outName) {
176     auto display = mDevice->getConnectedDisplay(displayId);
177     if (!display)
178         return Error::BAD_DISPLAY;
179
180     *outName = display->name();
181     return Error::NONE;
182 }
183
184 Error DrmComposerHal::getDisplayType(Display displayId, IComposerClient::DisplayType* outType) {
185     if (!mDevice->getConnectedDisplay(displayId))
186         return Error::BAD_DISPLAY;
187
188     *outType = IComposerClient::DisplayType::PHYSICAL;
189     return Error::NONE;
190 }
191
192 Error DrmComposerHal::getDozeSupport(Display displayId, bool* outSupport) {
193     if (!mDevice->getConnectedDisplay(displayId))
194         return Error::BAD_DISPLAY;
195
196     *outSupport = false;
197     return Error::NONE;
198 }
199
200 Error DrmComposerHal::getHdrCapabilities(Display displayId, hidl_vec<Hdr>* /*outTypes*/,
201         float* /*outMaxLuminance*/, float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
202     if (!mDevice->getConnectedDisplay(displayId))
203         return Error::BAD_DISPLAY;
204
205     return Error::NONE;
206 }
207
208 Error DrmComposerHal::setActiveConfig(Display displayId, Config config) {
209     auto display = mDevice->getConnectedDisplay(displayId);
210     if (!display)
211         return Error::BAD_DISPLAY;
212
213     return display->setMode(config) ? Error::NONE : Error::BAD_CONFIG;
214 }
215
216 Error DrmComposerHal::setColorMode(Display displayId, ColorMode mode) {
217     if (!mDevice->getConnectedDisplay(displayId))
218         return Error::BAD_DISPLAY;
219     if (mode != ColorMode::NATIVE)
220         return Error::UNSUPPORTED;
221
222     return Error::NONE;
223 }
224
225 Error DrmComposerHal::setPowerMode(Display displayId, IComposerClient::PowerMode mode) {
226     auto display = mDevice->getConnectedDisplay(displayId);
227     if (!display)
228         return Error::BAD_DISPLAY;
229
230     switch (mode) {
231     case IComposerClient::PowerMode::OFF:
232         display->disable();
233         return Error::NONE;
234     case IComposerClient::PowerMode::ON:
235         return display->enable() ? Error::NONE : Error::NO_RESOURCES;
236     case IComposerClient::PowerMode::DOZE:
237     case IComposerClient::PowerMode::DOZE_SUSPEND:
238         return Error::UNSUPPORTED;
239     default:
240         return Error::BAD_PARAMETER;
241     }
242 }
243
244 Error DrmComposerHal::setVsyncEnabled(Display displayId, IComposerClient::Vsync enabled) {
245     auto display = mDevice->getConnectedDisplay(displayId);
246     if (!display)
247         return Error::BAD_DISPLAY;
248
249     switch (enabled) {
250     case IComposerClient::Vsync::ENABLE:
251         display->enableVsync();
252         return Error::NONE;
253     case IComposerClient::Vsync::DISABLE:
254         display->disableVsync();
255         return Error::NONE;
256     default:
257         return Error::BAD_PARAMETER;
258     }
259 }
260
261 Error DrmComposerHal::setColorTransform(Display /*displayId*/,
262         const float* /*matrix*/, int32_t /*hint*/) {
263     return Error::UNSUPPORTED;
264 }
265
266 Error DrmComposerHal::setClientTarget(Display /*displayId*/,
267         buffer_handle_t target, int32_t acquireFence,
268         int32_t /*dataspace*/, const std::vector<hwc_rect_t>& /*damage*/) {
269     mBuffer = target;
270     mAcquireFence.reset(acquireFence);
271     return Error::NONE;
272 }
273
274 Error DrmComposerHal::setOutputBuffer(Display /*displayId*/,
275         buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) {
276     return Error::BAD_DISPLAY; // Virtual display
277 }
278
279 Error DrmComposerHal::validateDisplay(Display displayId, std::vector<Layer>* outChangedLayers,
280         std::vector<IComposerClient::Composition>* outCompositionTypes,
281         uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
282         std::vector<uint32_t>* /*outRequestMasks*/) {
283
284     for (auto& it : mLayers) {
285         auto layer = it.second;
286         if (layer.displayId == displayId
287                 && layer.composition != IComposerClient::Composition::CLIENT) {
288             // Force client composition for all layers
289             outChangedLayers->push_back(it.first);
290             outCompositionTypes->push_back(IComposerClient::Composition::CLIENT);
291         }
292     }
293
294     return Error::NONE;
295 }
296
297 Error DrmComposerHal::acceptDisplayChanges(Display /*displayId*/) {
298     return Error::NONE;
299 }
300
301 Error DrmComposerHal::presentDisplay(Display displayId, int32_t* /*outPresentFence*/,
302         std::vector<Layer>* /*outLayers*/, std::vector<int32_t>* /*outReleaseFences*/) {
303     auto display = mDevice->getConnectedDisplay(displayId);
304     if (!display)
305         return Error::BAD_DISPLAY;
306     if (!mBuffer)
307         return Error::NO_RESOURCES;
308
309     if (mAcquireFence >= 0) {
310         sync_wait(mAcquireFence, -1);
311         mAcquireFence.reset();
312     }
313
314     display->present(mBuffer);
315     // TODO: Present/release fence
316     return Error::NONE;
317 }
318
319 Error DrmComposerHal::setLayerCursorPosition(Display /*displayId*/,
320         Layer /*layer*/, int32_t /*x*/, int32_t /*y*/) {
321     return Error::NONE; // Ignored
322 }
323
324 Error DrmComposerHal::setLayerBuffer(Display /*displayId*/, Layer /*layer*/,
325         buffer_handle_t /*buffer*/, int32_t acquireFence) {
326
327     if (acquireFence >= 0) {
328         /*
329          * This buffer will be only used by client composition.
330          * During client composition, SurfaceFlinger will wait for the buffer
331          * (if necessary), so there is no need to do it here.
332          */
333         close(acquireFence);
334     }
335
336     return Error::NONE; // Ignored
337 }
338
339 Error DrmComposerHal::setLayerSurfaceDamage(Display /*displayId*/,
340         Layer /*layer*/, const std::vector<hwc_rect_t>& /*damage*/) {
341     return Error::NONE; // Ignored
342 }
343
344 Error DrmComposerHal::setLayerBlendMode(Display /*displayId*/,
345         Layer /*layer*/, int32_t /*mode*/) {
346     return Error::NONE; // Ignored
347 }
348
349 Error DrmComposerHal::setLayerColor(Display /*displayId*/,
350         Layer /*layer*/, IComposerClient::Color /*color*/) {
351     return Error::NONE; // Ignored
352 }
353
354 Error DrmComposerHal::setLayerCompositionType(Display displayId, Layer layer, int32_t type) {
355     auto i = mLayers.find(layer);
356     if (i == mLayers.end())
357         return Error::BAD_LAYER;
358     if (displayId != i->second.displayId)
359         return Error::BAD_DISPLAY;
360
361     i->second.composition = static_cast<IComposerClient::Composition>(type);
362     return Error::NONE;
363 }
364
365 Error DrmComposerHal::setLayerDataspace(Display /*displayId*/,
366         Layer /*layer*/, int32_t /*dataspace*/) {
367     return Error::NONE; // Ignored
368 }
369
370 Error DrmComposerHal::setLayerDisplayFrame(Display /*displayId*/,
371         Layer /*layer*/, const hwc_rect_t& /*frame*/) {
372     return Error::NONE; // Ignored
373 }
374
375 Error DrmComposerHal::setLayerPlaneAlpha(Display /*displayId*/,
376         Layer /*layer*/, float /*alpha*/) {
377     return Error::NONE; // Ignored
378 }
379
380 Error DrmComposerHal::setLayerSidebandStream(Display /*displayId*/,
381         Layer /*layer*/, buffer_handle_t /*stream*/) {
382     return Error::NONE; // Ignored
383 }
384
385 Error DrmComposerHal::setLayerSourceCrop(Display /*displayId*/,
386         Layer /*layer*/, const hwc_frect_t& /*crop*/) {
387     return Error::NONE; // Ignored
388 }
389
390 Error DrmComposerHal::setLayerTransform(Display /*displayId*/,
391         Layer /*layer*/, int32_t /*transform*/) {
392     return Error::NONE; // Ignored
393 }
394
395 Error DrmComposerHal::setLayerVisibleRegion(Display /*displayId*/,
396         Layer /*layer*/, const std::vector<hwc_rect_t>& /*visible*/) {
397     return Error::NONE; // Ignored
398 }
399
400 Error DrmComposerHal::setLayerZOrder(Display /*displayId*/,
401         Layer /*layer*/, uint32_t /*z*/) {
402     return Error::NONE; // Ignored
403 }
404
405 }  // namespace drmfb
406 }  // namespace V2_1
407 }  // namespace composer
408 }  // namespace graphics
409 }  // namespace hardware
410 }  // namespace android