blob: 9cc1f40184e3ca9b7466293d440e6353e5df34fd [file] [log] [blame]
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <apex/display.h>
#include <utils/Errors.h>
namespace android::display::impl {
/**
* Implementation of ADisplayConfig
*/
struct DisplayConfigImpl {
/**
* The width in pixels of the display configuration.
*/
int32_t width{1080};
/**
* The height in pixels of the display configuration.
*/
int32_t height{1920};
/**
* The refresh rate of the display configuration, in frames per second.
*/
float fps{60.0};
/**
* The vsync offset at which surfaceflinger runs, in nanoseconds.
*/
int64_t sfOffset{0};
/**
* The vsync offset at which applications run, in nanoseconds.
*/
int64_t appOffset{0};
};
// DisplayConfigImpl allocation is not managed through C++ memory apis, so
// preventing calling the destructor here.
static_assert(std::is_trivially_destructible<DisplayConfigImpl>::value);
/**
* Implementation of ADisplay
*/
struct DisplayImpl {
/**
* The type of the display, i.e. whether it is an internal or external
* display.
*/
ADisplayType type;
/**
* The preferred WCG dataspace
*/
ADataSpace wcgDataspace;
/**
* The preferred WCG pixel format
*/
AHardwareBuffer_Format wcgPixelFormat;
/**
* The config for this display.
*/
DisplayConfigImpl config;
};
// DisplayImpl allocation is not managed through C++ memory apis, so
// preventing calling the destructor here.
static_assert(std::is_trivially_destructible<DisplayImpl>::value);
} // namespace android::display::impl
using namespace android;
using namespace android::display::impl;
namespace android {
int ADisplay_acquirePhysicalDisplays(ADisplay*** outDisplays) {
// This is running on host, so there are no physical displays available.
// Create 1 fake display instead.
DisplayImpl** const impls = reinterpret_cast<DisplayImpl**>(
malloc(sizeof(DisplayImpl*) + sizeof(DisplayImpl)));
DisplayImpl* const displayData = reinterpret_cast<DisplayImpl*>(impls + 1);
displayData[0] = DisplayImpl{ADisplayType::DISPLAY_TYPE_INTERNAL,
ADataSpace::ADATASPACE_UNKNOWN,
AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
DisplayConfigImpl()};
impls[0] = displayData;
*outDisplays = reinterpret_cast<ADisplay**>(impls);
return 1;
}
void ADisplay_release(ADisplay** displays) {
if (displays == nullptr) {
return;
}
free(displays);
}
float ADisplay_getMaxSupportedFps(ADisplay* display) {
DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
return impl->config.fps;
}
ADisplayType ADisplay_getDisplayType(ADisplay* display) {
return reinterpret_cast<DisplayImpl*>(display)->type;
}
void ADisplay_getPreferredWideColorFormat(ADisplay* display, ADataSpace* outDataspace,
AHardwareBuffer_Format* outPixelFormat) {
DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
*outDataspace = impl->wcgDataspace;
*outPixelFormat = impl->wcgPixelFormat;
}
int ADisplay_getCurrentConfig(ADisplay* display, ADisplayConfig** outConfig) {
DisplayImpl* impl = reinterpret_cast<DisplayImpl*>(display);
*outConfig = reinterpret_cast<ADisplayConfig*>(&impl->config);
return OK;
}
int32_t ADisplayConfig_getWidth(ADisplayConfig* config) {
return reinterpret_cast<DisplayConfigImpl*>(config)->width;
}
int32_t ADisplayConfig_getHeight(ADisplayConfig* config) {
return reinterpret_cast<DisplayConfigImpl*>(config)->height;
}
float ADisplayConfig_getFps(ADisplayConfig* config) {
return reinterpret_cast<DisplayConfigImpl*>(config)->fps;
}
int64_t ADisplayConfig_getCompositorOffsetNanos(ADisplayConfig* config) {
return reinterpret_cast<DisplayConfigImpl*>(config)->sfOffset;
}
int64_t ADisplayConfig_getAppVsyncOffsetNanos(ADisplayConfig* config) {
return reinterpret_cast<DisplayConfigImpl*>(config)->appOffset;
}
} // namespace android