You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
8.5 KiB
238 lines
8.5 KiB
/*
|
|
* Copyright 2021 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.
|
|
*/
|
|
|
|
#ifndef ANDROID_HWC_DISPLAY_H
|
|
#define ANDROID_HWC_DISPLAY_H
|
|
|
|
#include <utils/Thread.h>
|
|
|
|
#include <optional>
|
|
#include <set>
|
|
#include <thread>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "Common.h"
|
|
#include "Composer.h"
|
|
#include "FencedBuffer.h"
|
|
#include "Layer.h"
|
|
|
|
namespace android {
|
|
|
|
class Composer;
|
|
class Device;
|
|
|
|
class Display {
|
|
public:
|
|
Display(Device& device, Composer* composer, hwc2_display_t id);
|
|
~Display();
|
|
|
|
Display(const Display& display) = delete;
|
|
Display& operator=(const Display& display) = delete;
|
|
|
|
Display(Display&& display) = delete;
|
|
Display& operator=(Display&& display) = delete;
|
|
|
|
HWC2::Error init(uint32_t width, uint32_t height, uint32_t dpiX,
|
|
uint32_t dpiY, uint32_t refreshRateHz,
|
|
const std::optional<std::vector<uint8_t>>& edid = std::nullopt);
|
|
|
|
HWC2::Error updateParameters(uint32_t width, uint32_t height, uint32_t dpiX,
|
|
uint32_t dpiY, uint32_t refreshRateHz,
|
|
const std::optional<std::vector<uint8_t>>& edid
|
|
= std::nullopt);
|
|
|
|
hwc2_display_t getId() const { return mId; }
|
|
|
|
Layer* getLayer(hwc2_layer_t layerHandle);
|
|
|
|
FencedBuffer& getClientTarget() { return mClientTarget; }
|
|
buffer_handle_t waitAndGetClientTargetBuffer();
|
|
|
|
const std::vector<Layer*>& getOrderedLayers() { return mOrderedLayers; }
|
|
|
|
HWC2::Error acceptChanges();
|
|
HWC2::Error createLayer(hwc2_layer_t* outLayerId);
|
|
HWC2::Error destroyLayer(hwc2_layer_t layerId);
|
|
HWC2::Error getActiveConfig(hwc2_config_t* outConfigId);
|
|
HWC2::Error getDisplayAttribute(hwc2_config_t configId, int32_t attribute,
|
|
int32_t* outValue);
|
|
HWC2::Error getDisplayAttributeEnum(hwc2_config_t configId,
|
|
HWC2::Attribute attribute,
|
|
int32_t* outValue);
|
|
HWC2::Error getChangedCompositionTypes(uint32_t* outNumElements,
|
|
hwc2_layer_t* outLayers,
|
|
int32_t* outTypes);
|
|
HWC2::Error getColorModes(uint32_t* outNumModes, int32_t* outModes);
|
|
HWC2::Error getConfigs(uint32_t* outNumConfigs, hwc2_config_t* outConfigIds);
|
|
HWC2::Error getDozeSupport(int32_t* outSupport);
|
|
HWC2::Error getHdrCapabilities(uint32_t* outNumTypes, int32_t* outTypes,
|
|
float* outMaxLuminance,
|
|
float* outMaxAverageLuminance,
|
|
float* outMinLuminance);
|
|
HWC2::Error getName(uint32_t* outSize, char* outName);
|
|
HWC2::Error addReleaseFenceLocked(int32_t fence);
|
|
HWC2::Error addReleaseLayerLocked(hwc2_layer_t layerId);
|
|
HWC2::Error getReleaseFences(uint32_t* outNumElements,
|
|
hwc2_layer_t* outLayers, int32_t* outFences);
|
|
HWC2::Error clearReleaseFencesAndIdsLocked();
|
|
HWC2::Error getRequests(int32_t* outDisplayRequests, uint32_t* outNumElements,
|
|
hwc2_layer_t* outLayers, int32_t* outLayerRequests);
|
|
HWC2::Error getType(int32_t* outType);
|
|
HWC2::Error present(int32_t* outRetireFence);
|
|
HWC2::Error setActiveConfig(hwc2_config_t configId);
|
|
HWC2::Error setClientTarget(buffer_handle_t target, int32_t acquireFence,
|
|
int32_t dataspace, hwc_region_t damage);
|
|
HWC2::Error setColorMode(int32_t mode);
|
|
HWC2::Error setColorTransform(const float* matrix, int32_t hint);
|
|
bool hasColorTransform() const { return mSetColorTransform; }
|
|
HWC2::Error setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence);
|
|
HWC2::Error setPowerMode(int32_t mode);
|
|
HWC2::Error setVsyncEnabled(int32_t enabled);
|
|
HWC2::Error setVsyncPeriod(uint32_t period);
|
|
HWC2::Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests);
|
|
HWC2::Error updateLayerZ(hwc2_layer_t layerId, uint32_t z);
|
|
HWC2::Error getClientTargetSupport(uint32_t width, uint32_t height,
|
|
int32_t format, int32_t dataspace);
|
|
HWC2::Error getDisplayIdentificationData(uint8_t* outPort,
|
|
uint32_t* outDataSize,
|
|
uint8_t* outData);
|
|
HWC2::Error getDisplayCapabilities(uint32_t* outNumCapabilities,
|
|
uint32_t* outCapabilities);
|
|
HWC2::Error getDisplayBrightnessSupport(bool* out_support);
|
|
HWC2::Error setDisplayBrightness(float brightness);
|
|
void lock() { mStateMutex.lock(); }
|
|
void unlock() { mStateMutex.unlock(); }
|
|
|
|
private:
|
|
class Config {
|
|
public:
|
|
Config(hwc2_config_t configId) : mId(configId) {}
|
|
|
|
Config(const Config& display) = default;
|
|
Config& operator=(const Config& display) = default;
|
|
|
|
Config(Config&& display) = default;
|
|
Config& operator=(Config&& display) = default;
|
|
|
|
hwc2_config_t getId() const { return mId; }
|
|
void setId(hwc2_config_t id) { mId = id; }
|
|
|
|
int32_t getAttribute(HWC2::Attribute attribute) const;
|
|
void setAttribute(HWC2::Attribute attribute, int32_t value);
|
|
|
|
std::string toString() const;
|
|
|
|
private:
|
|
hwc2_config_t mId;
|
|
std::unordered_map<HWC2::Attribute, int32_t> mAttributes;
|
|
};
|
|
|
|
// Stores changes requested from the device upon calling prepare().
|
|
// Handles change request to:
|
|
// - Layer composition type.
|
|
// - Layer hints.
|
|
class Changes {
|
|
public:
|
|
uint32_t getNumTypes() const {
|
|
return static_cast<uint32_t>(mTypeChanges.size());
|
|
}
|
|
|
|
uint32_t getNumLayerRequests() const {
|
|
return static_cast<uint32_t>(mLayerRequests.size());
|
|
}
|
|
|
|
const std::unordered_map<hwc2_layer_t, HWC2::Composition>& getTypeChanges()
|
|
const {
|
|
return mTypeChanges;
|
|
}
|
|
|
|
const std::unordered_map<hwc2_layer_t, HWC2::LayerRequest>&
|
|
getLayerRequests() const {
|
|
return mLayerRequests;
|
|
}
|
|
|
|
void addTypeChange(hwc2_layer_t layerId, HWC2::Composition type) {
|
|
mTypeChanges.insert({layerId, type});
|
|
}
|
|
|
|
void clearTypeChanges() { mTypeChanges.clear(); }
|
|
|
|
void addLayerRequest(hwc2_layer_t layerId, HWC2::LayerRequest request) {
|
|
mLayerRequests.insert({layerId, request});
|
|
}
|
|
|
|
private:
|
|
std::unordered_map<hwc2_layer_t, HWC2::Composition> mTypeChanges;
|
|
std::unordered_map<hwc2_layer_t, HWC2::LayerRequest> mLayerRequests;
|
|
};
|
|
|
|
// Generate sw vsync signal
|
|
class VsyncThread : public Thread {
|
|
public:
|
|
VsyncThread(Display& display) : mDisplay(display) {}
|
|
virtual ~VsyncThread() {}
|
|
|
|
VsyncThread(const VsyncThread&) = default;
|
|
VsyncThread& operator=(const VsyncThread&) = default;
|
|
|
|
VsyncThread(VsyncThread&&) = default;
|
|
VsyncThread& operator=(VsyncThread&&) = default;
|
|
|
|
private:
|
|
Display& mDisplay;
|
|
bool threadLoop() final;
|
|
};
|
|
|
|
private:
|
|
// The state of this display should only be modified from
|
|
// SurfaceFlinger's main loop, with the exception of when dump is
|
|
// called. To prevent a bad state from crashing us during a dump
|
|
// call, all public calls into Display must acquire this mutex.
|
|
mutable std::recursive_mutex mStateMutex;
|
|
|
|
Device& mDevice;
|
|
Composer* mComposer = nullptr;
|
|
const hwc2_display_t mId;
|
|
std::string mName;
|
|
HWC2::DisplayType mType = HWC2::DisplayType::Physical;
|
|
HWC2::PowerMode mPowerMode = HWC2::PowerMode::Off;
|
|
HWC2::Vsync mVsyncEnabled = HWC2::Vsync::Invalid;
|
|
uint32_t mVsyncPeriod;
|
|
sp<VsyncThread> mVsyncThread;
|
|
FencedBuffer mClientTarget;
|
|
// Will only be non-null after the Display has been validated and
|
|
// before it has been presented
|
|
std::unique_ptr<Changes> mChanges;
|
|
|
|
std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
|
|
// Ordered layers available after validate().
|
|
std::vector<Layer*> mOrderedLayers;
|
|
|
|
std::vector<hwc2_display_t> mReleaseLayerIds;
|
|
std::vector<int32_t> mReleaseFences;
|
|
std::optional<hwc2_config_t> mActiveConfigId;
|
|
std::unordered_map<hwc2_config_t, Config> mConfigs;
|
|
std::set<android_color_mode_t> mColorModes;
|
|
android_color_mode_t mActiveColorMode;
|
|
bool mSetColorTransform = false;
|
|
std::optional<std::vector<uint8_t>> mEdid;
|
|
};
|
|
|
|
} // namespace android
|
|
|
|
#endif
|