1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2019 Stephan Gerhold
4 #define LOG_TAG "drmfb-composer"
7 #include <android-base/logging.h>
8 #include <composer-hal/2.1/Composer.h>
10 #include "DrmComposer.h"
11 #include "DrmComposerHal.h"
20 android::sp<IComposer> createDrmComposer() {
21 auto device = std::make_unique<DrmDevice>();
22 if (!device->initialize()) {
26 return new hal::Composer{std::make_unique<DrmComposerHal>(std::move(device))};
29 DrmComposerHal::DrmComposerHal(std::unique_ptr<DrmDevice> device)
30 : mDevice(std::move(device)) {}
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;
38 std::string DrmComposerHal::dumpDebugInfo() {
42 void DrmComposerHal::registerEventCallback(EventCallback* callback) {
44 mDevice->enable(this);
47 void DrmComposerHal::unregisterEventCallback() {
48 LOG(INFO) << "Client destroyed, disabling displays";
56 void DrmComposerHal::onHotplug(const DrmDisplay& display, bool connected) {
57 mCallback->onHotplug(display.id(),
58 connected ? IComposerCallback::Connection::CONNECTED
59 : IComposerCallback::Connection::DISCONNECTED);
62 void DrmComposerHal::onVsync(const DrmDisplay& display, int64_t timestamp) {
63 mCallback->onVsync(display.id(), timestamp);
66 uint32_t DrmComposerHal::getMaxVirtualDisplayCount() {
67 return 0; // Not supported
70 Error DrmComposerHal::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
71 PixelFormat* /*format*/, Display* /*outDisplayId*/) {
72 return Error::NO_RESOURCES;
75 Error DrmComposerHal::destroyVirtualDisplay(Display /*displayId*/) {
76 return Error::BAD_DISPLAY;
79 Error DrmComposerHal::createLayer(Display displayId, Layer* outLayer) {
80 if (!mDevice->getConnectedDisplay(displayId))
81 return Error::BAD_DISPLAY;
83 *outLayer = mNextLayer++;
84 mLayers.emplace(*outLayer, displayId);
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;
100 Error DrmComposerHal::getActiveConfig(Display displayId, Config* outConfig) {
101 auto display = mDevice->getConnectedDisplay(displayId);
103 return Error::BAD_DISPLAY;
105 *outConfig = display->currentMode();
109 Error DrmComposerHal::getClientTargetSupport(Display displayId,
110 uint32_t width, uint32_t height, PixelFormat format, Dataspace dataspace) {
111 auto display = mDevice->getConnectedDisplay(displayId);
113 return Error::BAD_DISPLAY;
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;
121 Error DrmComposerHal::getColorModes(Display displayId, hidl_vec<ColorMode>* outModes) {
122 if (!mDevice->getConnectedDisplay(displayId))
123 return Error::BAD_DISPLAY;
125 *outModes = hidl_vec<ColorMode>{ColorMode::NATIVE};
129 Error DrmComposerHal::getDisplayAttribute(Display displayId, Config config,
130 IComposerClient::Attribute attribute, int32_t* outValue) {
131 auto display = mDevice->getConnectedDisplay(displayId);
133 return Error::BAD_DISPLAY;
136 case IComposerClient::Attribute::WIDTH:
137 *outValue = display->width(config);
139 case IComposerClient::Attribute::HEIGHT:
140 *outValue = display->height(config);
142 case IComposerClient::Attribute::VSYNC_PERIOD:
143 *outValue = display->vsyncPeriod(config);
145 case IComposerClient::Attribute::DPI_X:
146 *outValue = display->dpiX(config);
148 case IComposerClient::Attribute::DPI_Y:
149 *outValue = display->dpiY(config);
152 return Error::BAD_PARAMETER;
157 return Error::BAD_CONFIG;
159 return Error::UNSUPPORTED;
165 Error DrmComposerHal::getDisplayConfigs(Display displayId, hidl_vec<Config>* outConfigs) {
166 auto display = mDevice->getConnectedDisplay(displayId);
168 return Error::BAD_DISPLAY;
170 outConfigs->resize(display->modeCount());
171 std::iota(outConfigs->begin(), outConfigs->end(), 0);
175 Error DrmComposerHal::getDisplayName(Display displayId, hidl_string* outName) {
176 auto display = mDevice->getConnectedDisplay(displayId);
178 return Error::BAD_DISPLAY;
180 *outName = display->name();
184 Error DrmComposerHal::getDisplayType(Display displayId, IComposerClient::DisplayType* outType) {
185 if (!mDevice->getConnectedDisplay(displayId))
186 return Error::BAD_DISPLAY;
188 *outType = IComposerClient::DisplayType::PHYSICAL;
192 Error DrmComposerHal::getDozeSupport(Display displayId, bool* outSupport) {
193 if (!mDevice->getConnectedDisplay(displayId))
194 return Error::BAD_DISPLAY;
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;
208 Error DrmComposerHal::setActiveConfig(Display displayId, Config config) {
209 auto display = mDevice->getConnectedDisplay(displayId);
211 return Error::BAD_DISPLAY;
213 return display->setMode(config) ? Error::NONE : Error::BAD_CONFIG;
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;
225 Error DrmComposerHal::setPowerMode(Display displayId, IComposerClient::PowerMode mode) {
226 auto display = mDevice->getConnectedDisplay(displayId);
228 return Error::BAD_DISPLAY;
231 case IComposerClient::PowerMode::OFF:
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;
240 return Error::BAD_PARAMETER;
244 Error DrmComposerHal::setVsyncEnabled(Display displayId, IComposerClient::Vsync enabled) {
245 auto display = mDevice->getConnectedDisplay(displayId);
247 return Error::BAD_DISPLAY;
250 case IComposerClient::Vsync::ENABLE:
251 display->enableVsync();
253 case IComposerClient::Vsync::DISABLE:
254 display->disableVsync();
257 return Error::BAD_PARAMETER;
261 Error DrmComposerHal::setColorTransform(Display /*displayId*/,
262 const float* /*matrix*/, int32_t /*hint*/) {
263 return Error::UNSUPPORTED;
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*/) {
270 mAcquireFence.reset(acquireFence);
274 Error DrmComposerHal::setOutputBuffer(Display /*displayId*/,
275 buffer_handle_t /*buffer*/, int32_t /*releaseFence*/) {
276 return Error::BAD_DISPLAY; // Virtual display
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*/) {
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);
297 Error DrmComposerHal::acceptDisplayChanges(Display /*displayId*/) {
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);
305 return Error::BAD_DISPLAY;
307 return Error::NO_RESOURCES;
309 if (mAcquireFence >= 0) {
310 sync_wait(mAcquireFence, -1);
311 mAcquireFence.reset();
314 display->present(mBuffer);
315 // TODO: Present/release fence
319 Error DrmComposerHal::setLayerCursorPosition(Display /*displayId*/,
320 Layer /*layer*/, int32_t /*x*/, int32_t /*y*/) {
321 return Error::NONE; // Ignored
324 Error DrmComposerHal::setLayerBuffer(Display /*displayId*/, Layer /*layer*/,
325 buffer_handle_t /*buffer*/, int32_t acquireFence) {
327 if (acquireFence >= 0) {
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.
336 return Error::NONE; // Ignored
339 Error DrmComposerHal::setLayerSurfaceDamage(Display /*displayId*/,
340 Layer /*layer*/, const std::vector<hwc_rect_t>& /*damage*/) {
341 return Error::NONE; // Ignored
344 Error DrmComposerHal::setLayerBlendMode(Display /*displayId*/,
345 Layer /*layer*/, int32_t /*mode*/) {
346 return Error::NONE; // Ignored
349 Error DrmComposerHal::setLayerColor(Display /*displayId*/,
350 Layer /*layer*/, IComposerClient::Color /*color*/) {
351 return Error::NONE; // Ignored
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;
361 i->second.composition = static_cast<IComposerClient::Composition>(type);
365 Error DrmComposerHal::setLayerDataspace(Display /*displayId*/,
366 Layer /*layer*/, int32_t /*dataspace*/) {
367 return Error::NONE; // Ignored
370 Error DrmComposerHal::setLayerDisplayFrame(Display /*displayId*/,
371 Layer /*layer*/, const hwc_rect_t& /*frame*/) {
372 return Error::NONE; // Ignored
375 Error DrmComposerHal::setLayerPlaneAlpha(Display /*displayId*/,
376 Layer /*layer*/, float /*alpha*/) {
377 return Error::NONE; // Ignored
380 Error DrmComposerHal::setLayerSidebandStream(Display /*displayId*/,
381 Layer /*layer*/, buffer_handle_t /*stream*/) {
382 return Error::NONE; // Ignored
385 Error DrmComposerHal::setLayerSourceCrop(Display /*displayId*/,
386 Layer /*layer*/, const hwc_frect_t& /*crop*/) {
387 return Error::NONE; // Ignored
390 Error DrmComposerHal::setLayerTransform(Display /*displayId*/,
391 Layer /*layer*/, int32_t /*transform*/) {
392 return Error::NONE; // Ignored
395 Error DrmComposerHal::setLayerVisibleRegion(Display /*displayId*/,
396 Layer /*layer*/, const std::vector<hwc_rect_t>& /*visible*/) {
397 return Error::NONE; // Ignored
400 Error DrmComposerHal::setLayerZOrder(Display /*displayId*/,
401 Layer /*layer*/, uint32_t /*z*/) {
402 return Error::NONE; // Ignored
407 } // namespace composer
408 } // namespace graphics
409 } // namespace hardware
410 } // namespace android