Merge branch 'staging/lineage-15.1-caf-8996' of https://github.com/LineageOS/android_hardware_qcom_display into HEAD
Change-Id: Ic92c5edd0aef5c33dc84ef46ed38d8671d746da9
This commit is contained in:
commit
ee9aec33b6
|
@ -1,31 +1,31 @@
|
|||
/*
|
||||
* Copyight (c) 2017 The Linux Foundation. All ights reserved.
|
||||
*
|
||||
* Redistibution and use in souce and binary forms, with or without
|
||||
* modification, ae pemitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistibutions of souce code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaime.
|
||||
* * Redistibutions in binay form must reproduce the above
|
||||
* copyight notice, this list of conditions and the following
|
||||
* disclaime in the documentation and/o other materials provided
|
||||
* with the distibution.
|
||||
* * Neither the name of The Linux Foundation. no the names of its
|
||||
* contibutos may be used to endorse or promote products derived
|
||||
* fom this softwae without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_CONFIG_H__
|
||||
#define __DISPLAY_CONFIG_H__
|
||||
|
|
|
@ -71,7 +71,7 @@ static int gralloc_map_metadata(buffer_handle_t handle) {
|
|||
hnd, hnd->fd_metadata, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
|
||||
hnd->base_metadata = uint64_t(mappedAddress);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ static int gralloc_map(gralloc_module_t const* module,
|
|||
return -errno;
|
||||
}
|
||||
|
||||
hnd->base = uint64_t(mappedAddress) + hnd->offset;
|
||||
hnd->base = uint64_t(mappedAddress);
|
||||
} else {
|
||||
// Cannot map secure buffers or framebuffers, but still need to map
|
||||
// metadata for secure buffers.
|
||||
|
|
|
@ -48,16 +48,12 @@ AdrenoMemInfo *AdrenoMemInfo::GetInstance() {
|
|||
lock_guard<mutex> obj(s_lock);
|
||||
if (!s_instance) {
|
||||
s_instance = new AdrenoMemInfo();
|
||||
if (!s_instance->Init()) {
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
bool AdrenoMemInfo::Init() {
|
||||
AdrenoMemInfo::AdrenoMemInfo() {
|
||||
libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
|
||||
if (libadreno_utils_) {
|
||||
*reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
|
||||
|
@ -74,7 +70,6 @@ bool AdrenoMemInfo::Init() {
|
|||
::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
|
||||
} else {
|
||||
ALOGE(" Failed to load libadreno_utils.so");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the overriding property debug.gralloc.gfx_ubwc_disable
|
||||
|
@ -91,8 +86,6 @@ bool AdrenoMemInfo::Init() {
|
|||
(!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
|
||||
map_fb_ = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AdrenoMemInfo::~AdrenoMemInfo() {
|
||||
|
@ -170,6 +163,8 @@ void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsign
|
|||
width, height, format, 0, raster_mode, padding_threshold,
|
||||
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
|
||||
} else {
|
||||
*aligned_w = (unsigned int)ALIGN(width, 32);
|
||||
*aligned_h = (unsigned int)ALIGN(height, 32);
|
||||
ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,6 @@ typedef enum {
|
|||
|
||||
class AdrenoMemInfo {
|
||||
public:
|
||||
bool Init();
|
||||
|
||||
/*
|
||||
* Function to compute aligned width and aligned height based on
|
||||
* width, height, format and usage flags.
|
||||
|
@ -123,6 +121,7 @@ class AdrenoMemInfo {
|
|||
static AdrenoMemInfo *GetInstance();
|
||||
|
||||
private:
|
||||
AdrenoMemInfo();
|
||||
~AdrenoMemInfo();
|
||||
// link(s)to adreno surface padding library.
|
||||
int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
|
||||
|
|
|
@ -49,13 +49,6 @@ BufferManager::BufferManager() : next_id_(0) {
|
|||
map_fb_mem_ = true;
|
||||
}
|
||||
|
||||
// Enable UBWC for framebuffer
|
||||
if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
|
||||
(!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
|
||||
(!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
|
||||
ubwc_for_fb_ = true;
|
||||
}
|
||||
|
||||
handles_map_.clear();
|
||||
allocator_ = new Allocator();
|
||||
allocator_->Init();
|
||||
|
@ -199,7 +192,13 @@ void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDes
|
|||
|
||||
gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
|
||||
auto hnd = buf->handle;
|
||||
ALOGD_IF(DEBUG, "FreeBuffer handle:%p id: %" PRIu64, hnd, hnd->id);
|
||||
ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
ALOGE("FreeBuffer: Invalid handle: %p", hnd);
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
|
||||
hnd->fd, buf->ion_handle_main) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
|
@ -279,19 +278,12 @@ gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
|
|||
} else {
|
||||
private_handle_t *handle = const_cast<private_handle_t *>(hnd);
|
||||
err = ImportHandleLocked(handle);
|
||||
if (err == GRALLOC1_ERROR_NONE) {
|
||||
// TODO(user): See bug 35955598
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
|
||||
return GRALLOC1_ERROR_NONE; // Don't map secure buffer
|
||||
}
|
||||
err = MapBuffer(hnd);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
|
||||
ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
|
||||
ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
|
||||
std::lock_guard<std::mutex> lock(buffer_lock_);
|
||||
auto buf = GetBufferFromHandleLocked(hnd);
|
||||
if (buf == nullptr) {
|
||||
|
@ -329,16 +321,20 @@ gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
|
|||
err = MapBuffer(hnd);
|
||||
}
|
||||
|
||||
// Invalidate if CPU reads in software and there are non-CPU
|
||||
// writers. No need to do this for the metadata buffer as it is
|
||||
// only read/written in software.
|
||||
|
||||
// todo use handle here
|
||||
if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
|
||||
(hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
|
||||
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
|
||||
buf->ion_handle_main, CACHE_INVALIDATE)) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
|
||||
// Invalidate if CPU reads in software and there are non-CPU
|
||||
// writers. No need to do this for the metadata buffer as it is
|
||||
// only read/written in software.
|
||||
if ((cons_usage & (GRALLOC1_CONSUMER_USAGE_CPU_READ | GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
|
||||
&& (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER)) {
|
||||
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
|
||||
buf->ion_handle_main, CACHE_INVALIDATE)) {
|
||||
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -482,14 +478,14 @@ int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_han
|
|||
BufferInfo info = GetBufferInfo(descriptor);
|
||||
GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
|
||||
size = (bufferSize >= size) ? bufferSize : size;
|
||||
size = size * layer_count;
|
||||
|
||||
int err = 0;
|
||||
int flags = 0;
|
||||
auto page_size = UINT(getpagesize());
|
||||
AllocData data;
|
||||
data.align = GetDataAlignment(format, prod_usage, cons_usage);
|
||||
data.size = ALIGN(size, data.align);
|
||||
size = ALIGN(size, data.align) * layer_count;
|
||||
data.size = size;
|
||||
data.handle = (uintptr_t) handle;
|
||||
data.uncached = allocator_->UseUncached(prod_usage, cons_usage);
|
||||
|
||||
|
@ -526,7 +522,7 @@ int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_han
|
|||
descriptor.GetHeight(),
|
||||
format,
|
||||
buffer_type,
|
||||
size,
|
||||
data.size,
|
||||
prod_usage,
|
||||
cons_usage);
|
||||
|
||||
|
@ -558,6 +554,10 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
int format = va_arg(args, int);
|
||||
|
||||
native_handle_t **handle = va_arg(args, native_handle_t **);
|
||||
if (!handle) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
|
||||
native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
|
||||
if (hnd) {
|
||||
|
@ -567,7 +567,7 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
|
||||
hnd->size = size;
|
||||
hnd->offset = offset;
|
||||
hnd->base = uint64_t(base) + offset;
|
||||
hnd->base = uint64_t(base);
|
||||
hnd->gpuaddr = 0;
|
||||
BufferInfo info(width, height, format);
|
||||
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
|
||||
|
@ -585,6 +585,11 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
int format = va_arg(args, int);
|
||||
int *stride = va_arg(args, int *);
|
||||
unsigned int alignedw = 0, alignedh = 0;
|
||||
|
||||
if (!stride) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
BufferInfo info(width, width, format);
|
||||
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
|
||||
*stride = INT(alignedw);
|
||||
|
@ -597,6 +602,10 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!stride) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
BufferDim_t buffer_dim;
|
||||
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
|
||||
*stride = buffer_dim.sliceWidth;
|
||||
|
@ -614,6 +623,10 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!stride || !height) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
BufferDim_t buffer_dim;
|
||||
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
|
||||
*stride = buffer_dim.sliceWidth;
|
||||
|
@ -638,6 +651,10 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
int *aligned_width = va_arg(args, int *);
|
||||
int *aligned_height = va_arg(args, int *);
|
||||
int *tile_enabled = va_arg(args, int *);
|
||||
if (!aligned_width || !aligned_height || !tile_enabled) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
unsigned int alignedw, alignedh;
|
||||
BufferInfo info(width, height, format, prod_usage, cons_usage);
|
||||
*tile_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
|
||||
|
@ -649,9 +666,15 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
|
||||
private_handle_t *hnd = va_arg(args, private_handle_t *);
|
||||
int *color_space = va_arg(args, int *);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!color_space) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
*color_space = 0;
|
||||
#ifdef USE_COLOR_METADATA
|
||||
ColorMetaData color_metadata;
|
||||
|
@ -683,6 +706,11 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!ycbcr) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (GetYUVPlaneInfo(hnd, ycbcr)) {
|
||||
return GRALLOC1_ERROR_UNDEFINED;
|
||||
}
|
||||
|
@ -691,10 +719,15 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
|
||||
private_handle_t *hnd = va_arg(args, private_handle_t *);
|
||||
int *map_secure_buffer = va_arg(args, int *);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!map_secure_buffer) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) == 0) {
|
||||
*map_secure_buffer = 0;
|
||||
}
|
||||
|
@ -703,9 +736,15 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
|
||||
private_handle_t *hnd = va_arg(args, private_handle_t *);
|
||||
int *flag = va_arg(args, int *);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
*flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
|
||||
int linear_format = 0;
|
||||
if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
|
||||
|
@ -718,9 +757,15 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
|
||||
private_handle_t *hnd = va_arg(args, private_handle_t *);
|
||||
void **rgb_data = va_arg(args, void **);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!rgb_data) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (GetRgbDataAddress(hnd, rgb_data)) {
|
||||
return GRALLOC1_ERROR_UNDEFINED;
|
||||
}
|
||||
|
@ -737,6 +782,11 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
uint32_t *aligned_width = va_arg(args, uint32_t *);
|
||||
uint32_t *aligned_height = va_arg(args, uint32_t *);
|
||||
uint32_t *size = va_arg(args, uint32_t *);
|
||||
|
||||
if (!aligned_width || !aligned_height || !size) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
auto info = BufferInfo(width, height, format, producer_usage, consumer_usage);
|
||||
GetBufferSizeAndDimensions(info, size, aligned_width, aligned_height);
|
||||
// Align size
|
||||
|
@ -744,9 +794,8 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
*size = ALIGN(*size, align);
|
||||
} break;
|
||||
|
||||
// TODO(user): Break out similar functionality, preferably moving to a common lib.
|
||||
|
||||
case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
|
||||
std::lock_guard<std::mutex> lock(buffer_lock_);
|
||||
int width = va_arg(args, int);
|
||||
int height = va_arg(args, int);
|
||||
int format = va_arg(args, int);
|
||||
|
@ -765,9 +814,15 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
|
|||
case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
|
||||
private_handle_t *hnd = va_arg(args, private_handle_t *);
|
||||
int *flag = va_arg(args, int *);
|
||||
|
||||
if (private_handle_t::validate(hnd) != 0) {
|
||||
return GRALLOC1_ERROR_BAD_HANDLE;
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
|
||||
*flag = 0;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ class BufferManager {
|
|||
std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
|
||||
|
||||
bool map_fb_mem_ = false;
|
||||
bool ubwc_for_fb_ = false;
|
||||
Allocator *allocator_ = NULL;
|
||||
std::mutex buffer_lock_;
|
||||
std::mutex descriptor_lock_;
|
||||
|
|
|
@ -344,6 +344,10 @@ gralloc1_error_t GrallocImpl::GetLayerCount(gralloc1_device_t *device, buffer_ha
|
|||
|
||||
gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
|
||||
gralloc1_producer_usage_t *outUsage) {
|
||||
if (!outUsage) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
if (status == GRALLOC1_ERROR_NONE) {
|
||||
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
|
||||
|
@ -355,6 +359,10 @@ gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer
|
|||
|
||||
gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
|
||||
uint32_t *outStride) {
|
||||
if (!outStride) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
if (status == GRALLOC1_ERROR_NONE) {
|
||||
*outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
|
||||
|
@ -370,6 +378,10 @@ gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_
|
|||
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
|
||||
}
|
||||
|
||||
if (!device) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_descriptors, descriptors,
|
||||
out_buffers);
|
||||
|
@ -389,18 +401,21 @@ gralloc1_error_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_han
|
|||
}
|
||||
|
||||
gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
if (status == GRALLOC1_ERROR_NONE) {
|
||||
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
status = dev->buf_mgr_->ReleaseBuffer(hnd);
|
||||
if (!device || !buffer) {
|
||||
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
|
||||
}
|
||||
|
||||
return status;
|
||||
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
return dev->buf_mgr_->ReleaseBuffer(hnd);
|
||||
}
|
||||
|
||||
gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
|
||||
uint32_t *out_num_planes) {
|
||||
if (!out_num_planes) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
if (status == GRALLOC1_ERROR_NONE) {
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
|
@ -422,7 +437,8 @@ gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handl
|
|||
const gralloc1_rect_t *region, void **out_data,
|
||||
int32_t acquire_fence) {
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
if (status != GRALLOC1_ERROR_NONE) {
|
||||
if (status != GRALLOC1_ERROR_NONE || !out_data ||
|
||||
!region) { // currently we ignore the region/rect client wants to lock
|
||||
CloseFdIfValid(acquire_fence);
|
||||
return status;
|
||||
}
|
||||
|
@ -447,13 +463,8 @@ gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handl
|
|||
// return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
// currently we ignore the region/rect client wants to lock
|
||||
if (region == NULL) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
// TODO(user): Need to check if buffer was allocated with the same flags
|
||||
status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage);
|
||||
|
||||
*out_data = reinterpret_cast<void *>(hnd->base);
|
||||
|
||||
return status;
|
||||
|
@ -465,7 +476,12 @@ gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_
|
|||
const gralloc1_rect_t *region,
|
||||
struct android_flex_layout *out_flex_layout,
|
||||
int32_t acquire_fence) {
|
||||
void *out_data;
|
||||
if (!out_flex_layout) {
|
||||
CloseFdIfValid(acquire_fence);
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
void *out_data {};
|
||||
gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
|
||||
&out_data, acquire_fence);
|
||||
if (status != GRALLOC1_ERROR_NONE) {
|
||||
|
@ -481,11 +497,14 @@ gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_
|
|||
gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
|
||||
int32_t *release_fence) {
|
||||
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
|
||||
|
||||
if (status != GRALLOC1_ERROR_NONE) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!release_fence) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
|
||||
|
@ -495,6 +514,10 @@ gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_han
|
|||
}
|
||||
|
||||
gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
|
||||
if (!device) {
|
||||
return GRALLOC1_ERROR_BAD_VALUE;
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, operation);
|
||||
GrallocImpl const *dev = GRALLOC_IMPL(device);
|
||||
|
|
|
@ -61,7 +61,7 @@ inline int roundUpToPageSize(int x) {
|
|||
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD 0x00200000
|
||||
|
||||
/* This flag is used for SECURE display usecase */
|
||||
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x00800000
|
||||
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x01000000
|
||||
|
||||
/* Buffer content should be displayed on a primary display only */
|
||||
#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY 0x04000000
|
||||
|
@ -77,6 +77,7 @@ inline int roundUpToPageSize(int x) {
|
|||
#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP
|
||||
#define GRALLOC_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD
|
||||
#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP
|
||||
#define GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY
|
||||
#define GRALLOC_USAGE_PRIVATE_MM_HEAP 0x0
|
||||
|
||||
|
||||
|
|
|
@ -361,8 +361,14 @@ static int open_lights(const struct hw_module_t* module, char const* name,
|
|||
set_light = set_light_battery;
|
||||
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
|
||||
set_light = set_light_notifications;
|
||||
else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
|
||||
set_light = set_light_buttons;
|
||||
else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
|
||||
if (!access(BUTTON_FILE, F_OK)) {
|
||||
// enable light button when the file is present
|
||||
set_light = set_light_buttons;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
|
||||
set_light = set_light_attention;
|
||||
else
|
||||
|
|
|
@ -8,6 +8,7 @@ LOCAL_MODULE_TAGS := optional
|
|||
LOCAL_SHARED_LIBRARIES := $(common_libs) libbinder libqservice
|
||||
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
|
||||
LOCAL_HEADER_LIBRARIES := display_headers
|
||||
LOCAL_HEADER_LIBRARIES += libhardware_headers
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
|
||||
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
|
||||
|
|
|
@ -57,9 +57,9 @@ static int getExternalNode(const char *type) {
|
|||
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
int j = 0;
|
||||
|
||||
for(j = 0; j < HWC_NUM_DISPLAY_TYPES; j++) {
|
||||
for(j = 0; j < kFBNodeMax; j++) {
|
||||
snprintf (msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/class/graphics/fb%d/msm_fb_type", j);
|
||||
"/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
|
||||
displayDeviceFP = fopen(msmFbTypePath, "r");
|
||||
if(displayDeviceFP) {
|
||||
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
|
||||
|
@ -71,11 +71,11 @@ static int getExternalNode(const char *type) {
|
|||
}
|
||||
fclose(displayDeviceFP);
|
||||
} else {
|
||||
ALOGE("%s: Failed to open fb node %d", __func__, j);
|
||||
ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (j < HWC_NUM_DISPLAY_TYPES)
|
||||
if (j < kFBNodeMax)
|
||||
return j;
|
||||
else
|
||||
ALOGE("%s: Failed to find %s node", __func__, type);
|
||||
|
@ -186,12 +186,12 @@ int getEdidRawData(char *buffer)
|
|||
}
|
||||
|
||||
snprintf(msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/class/graphics/fb%d/edid_raw_data", node_id);
|
||||
"/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
|
||||
|
||||
edidFile = open(msmFbTypePath, O_RDONLY, 0);
|
||||
|
||||
if (edidFile < 0) {
|
||||
ALOGE("%s no edid raw data found", __func__);
|
||||
ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -214,11 +214,11 @@ bool isDPConnected() {
|
|||
}
|
||||
|
||||
snprintf(connectPath, sizeof(connectPath),
|
||||
"/sys/class/graphics/fb%d/connected", nodeId);
|
||||
"/sys/devices/virtual/graphics/fb%d/connected", nodeId);
|
||||
|
||||
connectFile = fopen(connectPath, "rb");
|
||||
if (!connectFile) {
|
||||
ALOGW("Failed to open connect node for device node %d", nodeId);
|
||||
ALOGW("Failed to open connect node for device node %s", connectPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -253,11 +253,11 @@ int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
|
|||
}
|
||||
|
||||
snprintf(configPath, sizeof(configPath),
|
||||
"/sys/class/graphics/fb%d/config", nodeId);
|
||||
"/sys/devices/virtual/graphics/fb%d/config", nodeId);
|
||||
|
||||
configFile = fopen(configPath, "rb");
|
||||
if (!configFile) {
|
||||
ALOGW("Failed to open config node for device node %d", nodeId);
|
||||
ALOGW("Failed to open config node for device node %s", configPath);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,6 @@ enum class DriverType {
|
|||
};
|
||||
DriverType getDriverType();
|
||||
const char *GetHALPixelFormatString(int format);
|
||||
|
||||
static const int kFBNodeMax = 4;
|
||||
}; //namespace qdutils
|
||||
#endif
|
||||
|
|
|
@ -664,6 +664,20 @@ class DisplayInterface {
|
|||
*/
|
||||
virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable) = 0;
|
||||
|
||||
/*! @brief Method to check whether a client target with the given properties
|
||||
can be supported/handled by hardware.
|
||||
|
||||
@param[in] width client target width
|
||||
@param[in] height client target height
|
||||
@param[in] format client target format
|
||||
@param[in] colorMetaData client target colorMetaData
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
|
||||
LayerBufferFormat format,
|
||||
const ColorMetaData &color_metadata) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~DisplayInterface() { }
|
||||
};
|
||||
|
|
|
@ -59,6 +59,7 @@ enum PendingAction {
|
|||
kDisableFrameCapture = BITMAP(7),
|
||||
kConfigureDetailedEnhancer = BITMAP(8),
|
||||
kInvalidatingAndkSetPanelBrightness = BITMAP(9),
|
||||
kModeSet = BITMAP(10),
|
||||
kGetDetailedEnhancerData = BITMAP(21),
|
||||
kNoAction = BITMAP(31),
|
||||
};
|
||||
|
@ -119,11 +120,12 @@ enum PPGlobalColorFeatureID {
|
|||
kGlobalColorFeatureDither,
|
||||
kGlobalColorFeatureGamut,
|
||||
kGlobalColorFeaturePADither,
|
||||
kGlobalColorFeatureCsc,
|
||||
kMaxNumPPFeatures,
|
||||
};
|
||||
|
||||
struct PPPendingParams {
|
||||
PendingAction action = kNoAction;
|
||||
int32_t action = kNoAction;
|
||||
void *params = NULL;
|
||||
};
|
||||
|
||||
|
@ -331,6 +333,21 @@ struct SDEPccCfg {
|
|||
SDEPccCfg *GetConfig() { return this; }
|
||||
};
|
||||
|
||||
struct SDECscCfg {
|
||||
static const uint32_t kCscMVSize = 9;
|
||||
static const uint32_t kCscBVSize = 3;
|
||||
static const uint32_t kCscLVSize = 6;
|
||||
uint32_t flags;
|
||||
uint32_t csc_mv[kCscMVSize];
|
||||
uint32_t csc_pre_bv[kCscBVSize];
|
||||
uint32_t csc_post_bv[kCscBVSize];
|
||||
uint32_t csc_pre_lv[kCscLVSize];
|
||||
uint32_t csc_post_lv[kCscLVSize];
|
||||
|
||||
static SDECscCfg *Init(uint32_t arg __attribute__((__unused__)));
|
||||
SDECscCfg *GetConfig() { return this; }
|
||||
};
|
||||
|
||||
struct SDEDitherCfg {
|
||||
uint32_t g_y_depth;
|
||||
uint32_t r_cr_depth;
|
||||
|
|
|
@ -162,6 +162,7 @@ struct HWResourceInfo {
|
|||
uint32_t num_smp_per_pipe = 0;
|
||||
uint32_t max_scale_up = 1;
|
||||
uint32_t max_scale_down = 1;
|
||||
float rot_downscale_max = 0.0f;
|
||||
uint64_t max_bandwidth_low = 0;
|
||||
uint64_t max_bandwidth_high = 0;
|
||||
uint32_t max_mixer_width = 2048;
|
||||
|
|
|
@ -226,6 +226,8 @@ void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_la
|
|||
DisplayCompositionContext *display_comp_ctx =
|
||||
reinterpret_cast<DisplayCompositionContext *>(comp_handle);
|
||||
StrategyConstraints *constraints = &display_comp_ctx->constraints;
|
||||
bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
|
||||
hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
|
||||
|
||||
constraints->safe_mode = safe_mode_;
|
||||
constraints->use_cursor = false;
|
||||
|
@ -234,10 +236,25 @@ void CompManager::PrepareStrategyConstraints(Handle comp_handle, HWLayers *hw_la
|
|||
// Limit 2 layer SDE Comp if its not a Primary Display.
|
||||
// Safe mode is the policy for External display on a low end device.
|
||||
if (!display_comp_ctx->is_primary_panel) {
|
||||
bool low_end_hw = ((hw_res_info_.num_vig_pipe + hw_res_info_.num_rgb_pipe +
|
||||
hw_res_info_.num_dma_pipe) <= kSafeModeThreshold);
|
||||
constraints->max_layers = max_sde_ext_layers_;
|
||||
constraints->safe_mode = (low_end_hw && !hw_res_info_.separate_rotator) ? true : safe_mode_;
|
||||
if(hw_layers->info.stack->flags.secure_present)
|
||||
secure_external_layer_ = true;
|
||||
else
|
||||
secure_external_layer_ = false;
|
||||
}
|
||||
|
||||
// When Secure layer is present on external, GPU composition should be policy
|
||||
// for Primary on low end devices
|
||||
if(display_comp_ctx->is_primary_panel && (registered_displays_.count() > 1)
|
||||
&& low_end_hw && secure_external_layer_) {
|
||||
DLOGV_IF(kTagCompManager,"Secure layer present for LET. Fallingback to GPU");
|
||||
hw_layers->info.stack->flags.skip_present = 1;
|
||||
for(auto &layer : hw_layers->info.stack->layers) {
|
||||
if(layer->composition != kCompositionGPUTarget) {
|
||||
layer->flags.skip = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a strategy fails after successfully allocating resources, then set safe mode
|
||||
|
|
|
@ -112,6 +112,7 @@ class CompManager : public DumpImpl {
|
|||
bool safe_mode_ = false; // Flag to notify all displays to be in resource crunch
|
||||
// mode, where strategy manager chooses the best strategy
|
||||
// that uses optimal number of pipes for each display
|
||||
bool secure_external_layer_ = false;
|
||||
HWResourceInfo hw_res_info_;
|
||||
BufferAllocator *buffer_allocator_ = NULL;
|
||||
ExtensionInterface *extension_intf_ = NULL;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
@ -73,6 +73,9 @@ DisplayError CoreImpl::Init() {
|
|||
goto CleanupOnError;
|
||||
}
|
||||
|
||||
if (hw_info_intf_ == NULL) {
|
||||
return kErrorResources;
|
||||
}
|
||||
error = hw_info_intf_->GetHWResourceInfo(&hw_resource_);
|
||||
if (error != kErrorNone) {
|
||||
goto CleanupOnError;
|
||||
|
|
|
@ -298,10 +298,9 @@ DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
|
|||
|
||||
CommitLayerParams(layer_stack);
|
||||
|
||||
if (comp_manager_->Commit(display_comp_ctx_, &hw_layers_)) {
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
|
||||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// check if feature list cache is dirty and pending.
|
||||
|
@ -1430,4 +1429,94 @@ DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
|
||||
LayerBufferFormat format,
|
||||
const ColorMetaData &color_metadata) {
|
||||
if (format != kFormatRGBA8888 && format != kFormatRGBA1010102) {
|
||||
DLOGW("Unsupported format = %d", format);
|
||||
return kErrorNotSupported;
|
||||
} else if (ValidateScaling(width, height) != kErrorNone) {
|
||||
DLOGW("Unsupported width = %d height = %d", width, height);
|
||||
return kErrorNotSupported;
|
||||
} else if (color_metadata.transfer && color_metadata.colorPrimaries) {
|
||||
DisplayError error = ValidateDataspace(color_metadata);
|
||||
if (error != kErrorNone) {
|
||||
DLOGW("Unsupported Transfer Request = %d Color Primary = %d",
|
||||
color_metadata.transfer, color_metadata.colorPrimaries);
|
||||
return error;
|
||||
}
|
||||
|
||||
// Check for BT2020 support
|
||||
if (color_metadata.colorPrimaries == ColorPrimaries_BT2020) {
|
||||
DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError DisplayBase::ValidateScaling(uint32_t width, uint32_t height) {
|
||||
uint32_t display_width = display_attributes_.x_pixels;
|
||||
uint32_t display_height = display_attributes_.y_pixels;
|
||||
|
||||
HWResourceInfo hw_resource_info = HWResourceInfo();
|
||||
hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
|
||||
float max_scale_down = FLOAT(hw_resource_info.max_scale_down);
|
||||
float max_scale_up = FLOAT(hw_resource_info.max_scale_up);
|
||||
|
||||
float scale_x = FLOAT(width / display_width);
|
||||
float scale_y = FLOAT(height / display_height);
|
||||
|
||||
if (scale_x > max_scale_down || scale_y > max_scale_down) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
|
||||
if ((1.0f / scale_x) > max_scale_up) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
|
||||
if ((1.0f / scale_y) > max_scale_up) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) {
|
||||
// Handle transfer
|
||||
switch (color_metadata.transfer) {
|
||||
case Transfer_sRGB:
|
||||
case Transfer_SMPTE_170M:
|
||||
case Transfer_SMPTE_ST2084:
|
||||
case Transfer_HLG:
|
||||
case Transfer_Linear:
|
||||
case Transfer_Gamma2_2:
|
||||
break;
|
||||
default:
|
||||
DLOGW("Unsupported Transfer Request = %d", color_metadata.transfer);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
// Handle colorPrimaries
|
||||
switch (color_metadata.colorPrimaries) {
|
||||
case ColorPrimaries_BT709_5:
|
||||
case ColorPrimaries_BT601_6_525:
|
||||
case ColorPrimaries_BT601_6_625:
|
||||
case ColorPrimaries_DCIP3:
|
||||
case ColorPrimaries_BT2020:
|
||||
break;
|
||||
default:
|
||||
DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -114,6 +114,9 @@ class DisplayBase : public DisplayInterface, DumpImpl {
|
|||
virtual DisplayError GetDisplayPort(DisplayPort *port);
|
||||
virtual bool IsPrimaryDisplay();
|
||||
virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
|
||||
virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
|
||||
LayerBufferFormat format,
|
||||
const ColorMetaData &color_metadata);
|
||||
|
||||
protected:
|
||||
DisplayError BuildLayerStackStats(LayerStack *layer_stack);
|
||||
|
@ -121,6 +124,8 @@ class DisplayBase : public DisplayInterface, DumpImpl {
|
|||
void CommitLayerParams(LayerStack *layer_stack);
|
||||
void PostCommitLayerParams(LayerStack *layer_stack);
|
||||
DisplayError HandleHDR(LayerStack *layer_stack);
|
||||
DisplayError ValidateScaling(uint32_t width, uint32_t height);
|
||||
DisplayError ValidateDataspace(const ColorMetaData &color_metadata);
|
||||
|
||||
// DumpImpl method
|
||||
void AppendDump(char *buffer, uint32_t length);
|
||||
|
|
|
@ -303,14 +303,19 @@ HWDeviceDRM::HWDeviceDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator
|
|||
}
|
||||
|
||||
DisplayError HWDeviceDRM::Init() {
|
||||
default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
|
||||
DRMLibLoader *drm_lib = DRMLibLoader::GetInstance();
|
||||
if (drm_lib == nullptr) {
|
||||
DLOGE("Failed to load DRM Lib");
|
||||
return kErrorResources;
|
||||
}
|
||||
default_mode_ = (drm_lib->IsLoaded() == false);
|
||||
|
||||
if (!default_mode_) {
|
||||
DRMMaster *drm_master = {};
|
||||
int dev_fd = -1;
|
||||
DRMMaster::GetInstance(&drm_master);
|
||||
drm_master->GetHandle(&dev_fd);
|
||||
DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
|
||||
drm_lib->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
|
||||
if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::PERIPHERAL, &token_)) {
|
||||
DLOGE("RegisterDisplay failed");
|
||||
return kErrorResources;
|
||||
|
|
|
@ -105,7 +105,12 @@ HWResourceInfo *HWInfoDRM::hw_resource_ = nullptr;
|
|||
|
||||
HWInfoDRM::HWInfoDRM() {
|
||||
DRMLogger::Set(new DRMLoggerImpl());
|
||||
default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
|
||||
drm_lib = DRMLibLoader::GetInstance();
|
||||
if (drm_lib == nullptr) {
|
||||
DLOGE("Failed to load DRM Library");
|
||||
return;
|
||||
}
|
||||
default_mode_ = (drm_lib->IsLoaded() == false);
|
||||
if (!default_mode_) {
|
||||
DRMMaster *drm_master = {};
|
||||
int dev_fd = -1;
|
||||
|
@ -115,20 +120,25 @@ HWInfoDRM::HWInfoDRM() {
|
|||
return;
|
||||
}
|
||||
drm_master->GetHandle(&dev_fd);
|
||||
DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
|
||||
drm_lib->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
|
||||
}
|
||||
}
|
||||
|
||||
HWInfoDRM::~HWInfoDRM() {
|
||||
delete hw_resource_;
|
||||
hw_resource_ = nullptr;
|
||||
if (hw_resource_ != nullptr) {
|
||||
delete hw_resource_;
|
||||
hw_resource_ = nullptr;
|
||||
}
|
||||
|
||||
if (drm_mgr_intf_) {
|
||||
DRMLibLoader::GetInstance()->FuncDestroyDRMManager()();
|
||||
if (drm_lib != nullptr) {
|
||||
drm_lib->FuncDestroyDRMManager()();
|
||||
}
|
||||
drm_mgr_intf_ = nullptr;
|
||||
}
|
||||
|
||||
DRMLibLoader::Destroy();
|
||||
drm_lib->Destroy();
|
||||
drm_lib = nullptr;
|
||||
DRMMaster::DestroyInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <private/hw_info_types.h>
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
#include <drm_lib_loader.h>
|
||||
|
||||
#include "hw_info_interface.h"
|
||||
|
||||
|
@ -72,6 +73,8 @@ class HWInfoDRM: public HWInfoInterface {
|
|||
static const int kHWMdssVersion5 = 500; // MDSS_V5
|
||||
static const int kMaxStringLength = 1024;
|
||||
static HWResourceInfo *hw_resource_;
|
||||
|
||||
drm_utils::DRMLibLoader *drm_lib = nullptr;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -53,6 +53,7 @@ DisplayError (*HWColorManager::SetFeature[])(const PPFeatureInfo &, msmfb_mdp_pp
|
|||
[kGlobalColorFeatureDither] = &HWColorManager::SetDither,
|
||||
[kGlobalColorFeatureGamut] = &HWColorManager::SetGamut,
|
||||
[kGlobalColorFeaturePADither] = &HWColorManager::SetPADither,
|
||||
[kGlobalColorFeatureCsc] = &HWColorManager::SetCSCLegacy,
|
||||
};
|
||||
|
||||
DisplayError HWColorManager::SetPCC(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
|
||||
|
@ -163,4 +164,25 @@ DisplayError HWColorManager::SetPADither(const PPFeatureInfo &feature,
|
|||
return ret;
|
||||
}
|
||||
|
||||
DisplayError HWColorManager::SetCSCLegacy(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params) {
|
||||
DisplayError ret = kErrorNone;
|
||||
|
||||
kernel_params->op = mdp_op_csc_cfg;
|
||||
kernel_params->data.csc_cfg_data.block = MDP_BLOCK_DMA_P;
|
||||
std::memcpy(&kernel_params->data.csc_cfg_data.csc_data, feature.GetConfigData(),
|
||||
sizeof(mdp_csc_cfg));
|
||||
|
||||
for( int row = 0; row < 3; row++) {
|
||||
DLOGV_IF(kTagQDCM, "kernel mv[%d][0]=0x%x mv[%d][1]=0x%x mv[%d][2]=0x%x\n",
|
||||
row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 0],
|
||||
row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 1],
|
||||
row, kernel_params->data.csc_cfg_data.csc_data.csc_mv[row*3 + 2]);
|
||||
DLOGV_IF(kTagQDCM, "kernel pre_bv[%d]=%x\n", row,
|
||||
kernel_params->data.csc_cfg_data.csc_data.csc_pre_bv[row]);
|
||||
DLOGV_IF(kTagQDCM, "kernel post_bv[%d]=%x\n", row,
|
||||
kernel_params->data.csc_cfg_data.csc_data.csc_post_bv[row]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved.
|
||||
/* Copyright (c) 2015-2017, The Linux Foundataion. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -47,7 +47,7 @@ class HWColorManager {
|
|||
static DisplayError SetDither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
|
||||
static DisplayError SetGamut(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
|
||||
static DisplayError SetPADither(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
|
||||
|
||||
static DisplayError SetCSCLegacy(const PPFeatureInfo &feature, msmfb_mdp_pp *kernel_params);
|
||||
static DisplayError (*SetFeature[kMaxNumPPFeatures])(const PPFeatureInfo &feature,
|
||||
msmfb_mdp_pp *kernel_params);
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
|
||||
#define __CLASS__ "HWHDMI"
|
||||
|
||||
#define MIN_HDR_RESET_WAITTIME_SEC 2
|
||||
|
||||
namespace sdm {
|
||||
|
||||
#ifdef MDP_HDR_STREAM
|
||||
|
@ -196,6 +198,10 @@ HWHDMI::HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info
|
|||
HWDevice::device_type_ = kDeviceHDMI;
|
||||
HWDevice::device_name_ = "HDMI Display Device";
|
||||
HWDevice::hw_info_intf_ = hw_info_intf;
|
||||
(void)hdr_reset_start_;
|
||||
(void)hdr_reset_end_;
|
||||
(void)reset_hdr_flag_;
|
||||
(void)cdm_color_space_;
|
||||
}
|
||||
|
||||
DisplayError HWHDMI::Init() {
|
||||
|
@ -443,8 +449,19 @@ DisplayError HWHDMI::Commit(HWLayers *hw_layers) {
|
|||
if (error != kErrorNone) {
|
||||
return error;
|
||||
}
|
||||
if (cdm_color_space_commit_) {
|
||||
#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
|
||||
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
|
||||
mdp_commit.cdm_color_space = cdm_color_space_;
|
||||
mdp_commit.flags |= MDP_COMMIT_UPDATE_CDM_COLOR_SPACE;
|
||||
#endif
|
||||
}
|
||||
|
||||
return HWDevice::Commit(hw_layers);
|
||||
error = HWDevice::Commit(hw_layers);
|
||||
if (cdm_color_space_commit_)
|
||||
cdm_color_space_commit_ = false;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
DisplayError HWHDMI::GetHWScanInfo(HWScanInfo *scan_info) {
|
||||
|
@ -994,23 +1011,17 @@ void HWHDMI::UpdateMixerAttributes() {
|
|||
}
|
||||
|
||||
DisplayError HWHDMI::UpdateHDRMetaData(HWLayers *hw_layers) {
|
||||
const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
|
||||
if (!hw_panel_info_.hdr_enabled || hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
|
||||
if (!hw_panel_info_.hdr_enabled) {
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
|
||||
#ifdef MDP_HDR_STREAM
|
||||
const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
|
||||
char hdr_stream_path[kMaxStringLength] = {};
|
||||
snprintf(hdr_stream_path, sizeof(hdr_stream_path), "%s%d/hdr_stream", fb_path_, fb_node_index_);
|
||||
|
||||
int fd = Sys::open_(hdr_stream_path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
DLOGE("Failed to open %s with error %s", hdr_stream_path, strerror(errno));
|
||||
return kErrorFileDescriptor;
|
||||
}
|
||||
|
||||
Layer hdr_layer = {};
|
||||
if (hdr_layer_info.operation == HWHDRLayerInfo::kSet && hdr_layer_info.layer_index > -1) {
|
||||
hdr_layer = *(hw_layers->info.stack->layers.at(UINT32(hdr_layer_info.layer_index)));
|
||||
|
@ -1021,47 +1032,89 @@ DisplayError HWHDMI::UpdateHDRMetaData(HWLayers *hw_layers) {
|
|||
const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
|
||||
const Primaries &primaries = mastering_display.primaries;
|
||||
|
||||
mdp_hdr_stream hdr_stream = {};
|
||||
mdp_hdr_stream_ctrl hdr_ctrl = {};
|
||||
if (hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
|
||||
int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
|
||||
hdr_stream.eotf = (eotf < 0) ? 0 : UINT32(eotf);
|
||||
hdr_stream.white_point_x = primaries.whitePoint[0];
|
||||
hdr_stream.white_point_y = primaries.whitePoint[1];
|
||||
hdr_stream.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
|
||||
hdr_stream.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
|
||||
hdr_stream.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
|
||||
hdr_stream.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
|
||||
hdr_stream.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
|
||||
hdr_stream.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
|
||||
hdr_stream.min_luminance = mastering_display.minDisplayLuminance;
|
||||
hdr_stream.max_luminance = mastering_display.maxDisplayLuminance/10000;
|
||||
hdr_stream.max_content_light_level = light_level.maxContentLightLevel;
|
||||
hdr_stream.max_average_light_level = light_level.minPicAverageLightLevel;
|
||||
hdr_ctrl.hdr_stream.eotf = (eotf < 0) ? 0 : UINT32(eotf);
|
||||
hdr_ctrl.hdr_stream.white_point_x = primaries.whitePoint[0];
|
||||
hdr_ctrl.hdr_stream.white_point_y = primaries.whitePoint[1];
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
|
||||
hdr_ctrl.hdr_stream.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
|
||||
hdr_ctrl.hdr_stream.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
|
||||
hdr_ctrl.hdr_stream.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
|
||||
hdr_ctrl.hdr_stream.min_luminance = mastering_display.minDisplayLuminance;
|
||||
hdr_ctrl.hdr_stream.max_luminance = mastering_display.maxDisplayLuminance/10000;
|
||||
hdr_ctrl.hdr_stream.max_content_light_level = light_level.maxContentLightLevel;
|
||||
hdr_ctrl.hdr_stream.max_average_light_level = light_level.minPicAverageLightLevel;
|
||||
hdr_ctrl.hdr_state = HDR_ENABLE;
|
||||
reset_hdr_flag_ = false;
|
||||
#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
|
||||
HWDevice::SetCSC(layer_buffer->color_metadata, &cdm_color_space_);
|
||||
cdm_color_space_commit_ = true;
|
||||
#endif
|
||||
// DP related
|
||||
int32_t pixel_encoding = GetPixelEncoding(hdr_layer.input_buffer);
|
||||
hdr_stream.pixel_encoding = (pixel_encoding < 0) ? 0 : UINT32(pixel_encoding);
|
||||
hdr_ctrl.hdr_stream.pixel_encoding = (pixel_encoding < 0) ? 0 : UINT32(pixel_encoding);
|
||||
int32_t colorimetry = GetColoriMetry(hdr_layer.input_buffer);
|
||||
hdr_stream.colorimetry = (colorimetry < 0) ? 0 : UINT32(colorimetry);
|
||||
hdr_stream.range = GetRange(hdr_layer.input_buffer.color_metadata.range);
|
||||
hdr_ctrl.hdr_stream.colorimetry = (colorimetry < 0) ? 0 : UINT32(colorimetry);
|
||||
hdr_ctrl.hdr_stream.range = GetRange(hdr_layer.input_buffer.color_metadata.range);
|
||||
int32_t bits_per_component = GetBitsPerComponent(hdr_layer.input_buffer);
|
||||
hdr_stream.bits_per_component = (bits_per_component < 0) ? 0 : UINT32(bits_per_component);
|
||||
hdr_stream.content_type = GetContentType(hdr_layer.input_buffer);
|
||||
hdr_ctrl.hdr_stream.bits_per_component =
|
||||
(bits_per_component < 0) ? 0 : UINT32(bits_per_component);
|
||||
hdr_ctrl.hdr_stream.content_type = GetContentType(hdr_layer.input_buffer);
|
||||
|
||||
DLOGV_IF(kTagDriverConfig, "HDR Stream : MaxDisplayLuminance = %d MinDisplayLuminance = %d\n"
|
||||
"MaxContentLightLevel = %d MaxAverageLightLevel = %d Red_x = %d Red_y = %d Green_x = %d\n"
|
||||
"Green_y = %d Blue_x = %d Blue_y = %d WhitePoint_x = %d WhitePoint_y = %d EOTF = %d\n"
|
||||
"PixelEncoding = %d Colorimetry = %d Range = %d BPC = %d ContentType = %d",
|
||||
hdr_stream.max_luminance, hdr_stream.min_luminance, hdr_stream.max_content_light_level,
|
||||
hdr_stream.max_average_light_level, hdr_stream.display_primaries_x[0],
|
||||
hdr_stream.display_primaries_y[0], hdr_stream.display_primaries_x[1],
|
||||
hdr_stream.display_primaries_y[1], hdr_stream.display_primaries_x[2],
|
||||
hdr_stream.display_primaries_y[2], hdr_stream.white_point_x, hdr_stream.white_point_x,
|
||||
hdr_stream.eotf, hdr_stream.pixel_encoding, hdr_stream.colorimetry, hdr_stream.range,
|
||||
hdr_stream.bits_per_component, hdr_stream.content_type);
|
||||
DLOGV_IF(kTagDriverConfig, "kSet: HDR Stream : MaxDisplayLuminance = %d\n"
|
||||
"MinDisplayLuminance = %d MaxContentLightLevel = %d MaxAverageLightLevel = %d\n"
|
||||
"Red_x = %d Red_y = %d Green_x = %d Green_y = %d Blue_x = %d Blue_y = %d\n"
|
||||
"WhitePoint_x = %d WhitePoint_y = %d EOTF = %d PixelEncoding = %d Colorimetry = %d\n"
|
||||
"Range = %d BPC = %d ContentType = %d hdr_state = %d",
|
||||
hdr_ctrl.hdr_stream.max_luminance, hdr_ctrl.hdr_stream.min_luminance,
|
||||
hdr_ctrl.hdr_stream.max_content_light_level, hdr_ctrl.hdr_stream.max_average_light_level,
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[0], hdr_ctrl.hdr_stream.display_primaries_y[0],
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[1], hdr_ctrl.hdr_stream.display_primaries_y[1],
|
||||
hdr_ctrl.hdr_stream.display_primaries_x[2], hdr_ctrl.hdr_stream.display_primaries_y[2],
|
||||
hdr_ctrl.hdr_stream.white_point_x, hdr_ctrl.hdr_stream.white_point_x,
|
||||
hdr_ctrl.hdr_stream.eotf, hdr_ctrl.hdr_stream.pixel_encoding,
|
||||
hdr_ctrl.hdr_stream.colorimetry, hdr_ctrl.hdr_stream.range,
|
||||
hdr_ctrl.hdr_stream.bits_per_component, hdr_ctrl.hdr_stream.content_type,
|
||||
hdr_ctrl.hdr_state);
|
||||
} else if (hdr_layer_info.operation == HWHDRLayerInfo::kReset) {
|
||||
memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
|
||||
hdr_ctrl.hdr_state = HDR_RESET;
|
||||
reset_hdr_flag_ = true;
|
||||
hdr_reset_start_ = time(NULL);
|
||||
#ifdef MDP_COMMIT_UPDATE_CDM_COLOR_SPACE
|
||||
cdm_color_space_ = (mdp_color_space) MDP_CSC_DEFAULT;
|
||||
cdm_color_space_commit_ = true;
|
||||
#endif
|
||||
DLOGV_IF(kTagDriverConfig, "kReset: HDR Stream: HDR_RESET");
|
||||
} else if (hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
|
||||
if (reset_hdr_flag_) {
|
||||
hdr_reset_end_ = time(NULL);
|
||||
|
||||
if ((hdr_reset_end_ - hdr_reset_start_) >= MIN_HDR_RESET_WAITTIME_SEC) {
|
||||
reset_hdr_flag_ = false;
|
||||
memset(&hdr_ctrl.hdr_stream, 0, sizeof(hdr_ctrl.hdr_stream));
|
||||
hdr_ctrl.hdr_state = HDR_DISABLE;
|
||||
DLOGV_IF(kTagDriverConfig, "kNoOp: HDR Stream: HDR_DISABLE");
|
||||
} else {
|
||||
return kErrorNone;
|
||||
}
|
||||
} else {
|
||||
return kErrorNone;
|
||||
}
|
||||
}
|
||||
|
||||
const void *hdr_metadata = reinterpret_cast<const void*>(&hdr_stream);
|
||||
ssize_t len = Sys::pwrite_(fd, hdr_metadata, sizeof(hdr_stream), 0);
|
||||
int fd = Sys::open_(hdr_stream_path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
DLOGE("Failed to open %s with error %s", hdr_stream_path, strerror(errno));
|
||||
return kErrorFileDescriptor;
|
||||
}
|
||||
|
||||
const void *hdr_metadata = reinterpret_cast<const void*>(&hdr_ctrl);
|
||||
ssize_t len = Sys::pwrite_(fd, hdr_metadata, sizeof(hdr_ctrl), 0);
|
||||
if (len <= 0) {
|
||||
DLOGE("Failed to write hdr_metadata");
|
||||
error = kErrorUndefined;
|
||||
|
|
|
@ -118,6 +118,10 @@ class HWHDMI : public HWDevice {
|
|||
vector<HWS3DMode> supported_s3d_modes_;
|
||||
msm_hdmi_s3d_mode active_mdp_s3d_mode_ = HDMI_S3D_NONE;
|
||||
uint32_t frame_rate_ = 0;
|
||||
time_t hdr_reset_start_ = 0, hdr_reset_end_ = 0;
|
||||
bool reset_hdr_flag_ = false;
|
||||
mdp_color_space cdm_color_space_ = {};
|
||||
bool cdm_color_space_commit_ = false;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -154,7 +154,9 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
|
|||
while (Sys::getline_(fs, line)) {
|
||||
// parse the line and update information accordingly
|
||||
if (!ParseString(line.c_str(), tokens, max_count, ":, =\n", &token_count)) {
|
||||
if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
|
||||
if (!strncmp(tokens[0], "mdp_version", strlen("mdp_version"))) {
|
||||
hw_resource_->hw_version = UINT32(atoi(tokens[1])); // HW Version 3/5
|
||||
} else if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
|
||||
hw_resource_->hw_revision = UINT32(atoi(tokens[1])); // HW Rev, v1/v2
|
||||
} else if (!strncmp(tokens[0], "rot_input_fmts", strlen("rot_input_fmts"))) {
|
||||
ParseFormats(&tokens[1], (token_count - 1), kHWRotatorInput, hw_resource_);
|
||||
|
@ -168,6 +170,8 @@ DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
|
|||
hw_resource_->max_scale_down = UINT32(atoi(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
|
||||
hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "rot_dwnscale_max", strlen("rot_dwnscale_max"))) {
|
||||
hw_resource_->rot_downscale_max = FLOAT(atoi(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
|
||||
hw_resource_->max_bandwidth_low = UINT64(atol(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
|
||||
|
|
|
@ -604,14 +604,22 @@ DisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) {
|
|||
uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA, DITHER, GAMUT };
|
||||
#endif
|
||||
|
||||
for (int i(0); i < kMaxNumPPFeatures; i++) {
|
||||
version.pp_feature = feature_id_mapping[i];
|
||||
if (hw_resource_.hw_version != kHWMdssVersion3) {
|
||||
// Do not query kGlobalColorFeatureCsc for kHWMdssVersion5
|
||||
for (int i(0); i < (kMaxNumPPFeatures - 1); i++) {
|
||||
version.pp_feature = feature_id_mapping[i];
|
||||
|
||||
if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP_GET_FEATURE_VERSION), &version) < 0) {
|
||||
IOCTL_LOGE(MSMFB_MDP_PP_GET_FEATURE_VERSION, device_type_);
|
||||
return kErrorHardware;
|
||||
if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP_GET_FEATURE_VERSION), &version) < 0) {
|
||||
IOCTL_LOGE(MSMFB_MDP_PP_GET_FEATURE_VERSION, device_type_);
|
||||
return kErrorHardware;
|
||||
}
|
||||
vers->version[i] = version.version_info;
|
||||
}
|
||||
} else {
|
||||
for (int i(0); i < kMaxNumPPFeatures; i++) {
|
||||
version.pp_feature = feature_id_mapping[i];
|
||||
vers->version[i] = mdp_pp_legacy;
|
||||
}
|
||||
vers->version[i] = version.version_info;
|
||||
}
|
||||
|
||||
return kErrorNone;
|
||||
|
|
|
@ -73,6 +73,7 @@ class HWPrimary : public HWDevice {
|
|||
kMaxSysfsCommandLength = 12,
|
||||
};
|
||||
|
||||
static const int kHWMdssVersion3 = 3;
|
||||
DisplayError PopulateDisplayAttributes();
|
||||
void InitializeConfigs();
|
||||
bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
|
||||
|
|
|
@ -17,7 +17,7 @@ LOCAL_CLANG := true
|
|||
LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \
|
||||
libutils libcutils libsync libmemalloc libqdutils libdl \
|
||||
libpowermanager libsdmutils libgpu_tonemapper libc++ liblog \
|
||||
libdrmutils libui
|
||||
libdrmutils libui libbfqio_vendor
|
||||
|
||||
LOCAL_SRC_FILES := hwc_session.cpp \
|
||||
hwc_display.cpp \
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <utils/constants.h>
|
||||
#include <utils/String16.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <bfqio/bfqio.h>
|
||||
#include <hardware_legacy/uevent.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/prctl.h>
|
||||
|
@ -1430,6 +1431,7 @@ void* HWCSession::HWCUeventThreadHandler() {
|
|||
uevent_locker_.Lock();
|
||||
prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
|
||||
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
||||
android_set_rt_ioprio(0, 1);
|
||||
if (!uevent_init()) {
|
||||
DLOGE("Failed to init uevent");
|
||||
pthread_exit(0);
|
||||
|
|
|
@ -22,7 +22,7 @@ LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware li
|
|||
libutils libcutils libsync libqdutils libqdMetaData libdl libdrmutils \
|
||||
libsdmutils libc++ liblog libgrallocutils libdl \
|
||||
vendor.display.config@1.0_vendor libhidlbase libhidltransport \
|
||||
libui libgpu_tonemapper
|
||||
libui libgpu_tonemapper libbfqio_vendor
|
||||
|
||||
ifneq ($(TARGET_USES_GRALLOC1), true)
|
||||
LOCAL_SHARED_LIBRARIES += libmemalloc
|
||||
|
@ -42,7 +42,8 @@ LOCAL_SRC_FILES := hwc_session.cpp \
|
|||
../hwc/cpuhint.cpp \
|
||||
../hwc/hwc_socket_handler.cpp \
|
||||
display_null.cpp \
|
||||
hwc_tonemapper.cpp
|
||||
hwc_tonemapper.cpp \
|
||||
hwc_display_external_test.cpp
|
||||
|
||||
ifneq ($(TARGET_USES_GRALLOC1), true)
|
||||
LOCAL_SRC_FILES += ../hwc/hwc_buffer_allocator.cpp
|
||||
|
|
|
@ -95,6 +95,8 @@ class DisplayNull : public DisplayInterface {
|
|||
MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
|
||||
MAKE_NO_OP(GetDisplayPort(DisplayPort *))
|
||||
MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
|
||||
MAKE_NO_OP(GetClientTargetSupport(uint32_t, uint32_t, LayerBufferFormat,
|
||||
const ColorMetaData &))
|
||||
|
||||
private:
|
||||
bool active_ = false;
|
||||
|
|
|
@ -41,27 +41,45 @@
|
|||
|
||||
namespace sdm {
|
||||
|
||||
HWCBufferAllocator::HWCBufferAllocator() {
|
||||
DisplayError HWCBufferAllocator::Init() {
|
||||
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
|
||||
if (err != 0) {
|
||||
DLOGE("FATAL: can not open GRALLOC module");
|
||||
} else {
|
||||
gralloc1_open(module_, &gralloc_device_);
|
||||
DLOGE("FATAL: can not get GRALLOC module");
|
||||
return kErrorResources;
|
||||
}
|
||||
if (gralloc_device_ != nullptr) {
|
||||
ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
|
||||
Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
|
||||
Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
|
||||
|
||||
err = gralloc1_open(module_, &gralloc_device_);
|
||||
if (err != 0) {
|
||||
DLOGE("FATAL: can not open GRALLOC device");
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
if (gralloc_device_ == nullptr) {
|
||||
DLOGE("FATAL: gralloc device is null");
|
||||
return kErrorResources;
|
||||
}
|
||||
|
||||
ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
|
||||
Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
|
||||
Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
|
||||
Unlock_ = reinterpret_cast<GRALLOC1_PFN_UNLOCK>(
|
||||
gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_UNLOCK));
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
HWCBufferAllocator::~HWCBufferAllocator() {
|
||||
DisplayError HWCBufferAllocator::Deinit() {
|
||||
if (gralloc_device_ != nullptr) {
|
||||
gralloc1_close(gralloc_device_);
|
||||
int err = gralloc1_close(gralloc_device_);
|
||||
if (err != 0) {
|
||||
DLOGE("FATAL: can not close GRALLOC device");
|
||||
return kErrorResources;
|
||||
}
|
||||
}
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
|
||||
|
@ -80,6 +98,10 @@ DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
|
|||
alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
|
||||
}
|
||||
|
||||
if (buffer_config.secure_camera) {
|
||||
alloc_flags |= GRALLOC1_PRODUCER_USAGE_CAMERA;
|
||||
}
|
||||
|
||||
if (!buffer_config.cache) {
|
||||
// Allocate uncached buffers
|
||||
alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
|
||||
|
@ -90,7 +112,7 @@ DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
|
|||
}
|
||||
|
||||
uint64_t producer_usage = alloc_flags;
|
||||
uint64_t consumer_usage = alloc_flags;
|
||||
uint64_t consumer_usage = (alloc_flags | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
|
||||
// CreateBuffer
|
||||
private_handle_t *hnd = nullptr;
|
||||
Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
|
||||
|
@ -99,6 +121,8 @@ DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
|
|||
if (hnd) {
|
||||
alloc_buffer_info->fd = hnd->fd;
|
||||
alloc_buffer_info->stride = UINT32(hnd->width);
|
||||
alloc_buffer_info->aligned_width = UINT32(hnd->width);
|
||||
alloc_buffer_info->aligned_height = UINT32(hnd->height);
|
||||
alloc_buffer_info->size = hnd->size;
|
||||
} else {
|
||||
DLOGE("Failed to allocate memory");
|
||||
|
@ -137,6 +161,9 @@ void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int for
|
|||
if (alloc_type & GRALLOC_USAGE_HW_FB) {
|
||||
consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
|
||||
}
|
||||
if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
|
||||
producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
|
||||
}
|
||||
|
||||
Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
|
||||
producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
|
||||
|
@ -375,4 +402,8 @@ DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int a
|
|||
return kErrorNone;
|
||||
}
|
||||
|
||||
DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int* release_fence) {
|
||||
return (DisplayError)(Unlock_(gralloc_device_, handle, release_fence));
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -45,9 +45,8 @@ inline Type ALIGN(Type x, Type align) {
|
|||
|
||||
class HWCBufferAllocator : public BufferAllocator {
|
||||
public:
|
||||
HWCBufferAllocator();
|
||||
~HWCBufferAllocator();
|
||||
|
||||
DisplayError Init();
|
||||
DisplayError Deinit();
|
||||
DisplayError AllocateBuffer(BufferInfo *buffer_info);
|
||||
DisplayError FreeBuffer(BufferInfo *buffer_info);
|
||||
uint32_t GetBufferSize(BufferInfo *buffer_info);
|
||||
|
@ -62,6 +61,7 @@ class HWCBufferAllocator : public BufferAllocator {
|
|||
uint32_t *num_planes);
|
||||
int SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags);
|
||||
DisplayError MapBuffer(const private_handle_t *handle, int acquire_fence);
|
||||
DisplayError UnmapBuffer(const private_handle_t *handle, int* release_fence);
|
||||
|
||||
private:
|
||||
gralloc1_device_t *gralloc_device_ = nullptr;
|
||||
|
@ -69,6 +69,7 @@ class HWCBufferAllocator : public BufferAllocator {
|
|||
GRALLOC1_PFN_RELEASE ReleaseBuffer_ = nullptr;
|
||||
GRALLOC1_PFN_PERFORM Perform_ = nullptr;
|
||||
GRALLOC1_PFN_LOCK Lock_ = nullptr;
|
||||
GRALLOC1_PFN_UNLOCK Unlock_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -122,6 +122,16 @@ HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
|
|||
return status;
|
||||
}
|
||||
|
||||
HWC2::Error HWCColorMode::RestoreColorTransform() {
|
||||
DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix_);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to set Color Transform");
|
||||
return HWC2::Error::BadParameter;
|
||||
}
|
||||
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
|
||||
if (!matrix || (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
|
||||
hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)) {
|
||||
|
@ -451,6 +461,7 @@ void HWCDisplay::BuildLayerStack() {
|
|||
display_rect_ = LayerRect();
|
||||
metadata_refresh_rate_ = 0;
|
||||
auto working_primaries = ColorPrimaries_BT709_5;
|
||||
bool secure_display_active = false;
|
||||
|
||||
// Add one layer for fb target
|
||||
// TODO(user): Add blit target layers
|
||||
|
@ -463,12 +474,11 @@ void HWCDisplay::BuildLayerStack() {
|
|||
layer->flags.solid_fill = true;
|
||||
}
|
||||
|
||||
if (!hwc_layer->ValidateAndSetCSC()) {
|
||||
#ifdef FEATURE_WIDE_COLOR
|
||||
if (!hwc_layer->SupportedDataspace()) {
|
||||
layer->flags.skip = true;
|
||||
DLOGW_IF(kTagStrategy, "Unsupported dataspace: 0x%x", hwc_layer->GetLayerDataspace());
|
||||
}
|
||||
layer->flags.skip = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
working_primaries = WidestPrimaries(working_primaries,
|
||||
layer->input_buffer.color_metadata.colorPrimaries);
|
||||
|
@ -507,6 +517,10 @@ void HWCDisplay::BuildLayerStack() {
|
|||
layer_stack_.flags.skip_present = true;
|
||||
}
|
||||
|
||||
if (layer->input_buffer.flags.secure_display) {
|
||||
secure_display_active = true;
|
||||
}
|
||||
|
||||
if (hwc_layer->GetClientRequestedCompositionType() == HWC2::Composition::Cursor) {
|
||||
// Currently we support only one HWCursor & only at top most z-order
|
||||
if ((*layer_set_.rbegin())->GetId() == hwc_layer->GetId()) {
|
||||
|
@ -579,7 +593,19 @@ void HWCDisplay::BuildLayerStack() {
|
|||
// TODO(user): Set correctly when SDM supports geometry_changes as bitmask
|
||||
layer_stack_.flags.geometry_changed = UINT32(geometry_changes_ > 0);
|
||||
// Append client target to the layer stack
|
||||
layer_stack_.layers.push_back(client_target_->GetSDMLayer());
|
||||
|
||||
Layer *sdm_client_target = client_target_->GetSDMLayer();
|
||||
layer_stack_.layers.push_back(sdm_client_target);
|
||||
// fall back frame composition to GPU when client target is 10bit
|
||||
// TODO(user): clarify the behaviour from Client(SF) and SDM Extn -
|
||||
// when handling 10bit FBT, as it would affect blending
|
||||
if (Is10BitFormat(sdm_client_target->input_buffer.format)) {
|
||||
// Must fall back to client composition
|
||||
MarkLayersForClientComposition();
|
||||
}
|
||||
|
||||
// set secure display
|
||||
SetSecureDisplay(secure_display_active);
|
||||
}
|
||||
|
||||
void HWCDisplay::BuildSolidFillStack() {
|
||||
|
@ -708,15 +734,20 @@ HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode) {
|
|||
|
||||
HWC2::Error HWCDisplay::GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
|
||||
int32_t dataspace) {
|
||||
DisplayConfigVariableInfo variable_config;
|
||||
display_intf_->GetFrameBufferConfig(&variable_config);
|
||||
// TODO(user): Support scaled configurations, other formats and other dataspaces
|
||||
if (format != HAL_PIXEL_FORMAT_RGBA_8888 || dataspace != HAL_DATASPACE_UNKNOWN ||
|
||||
width != variable_config.x_pixels || height != variable_config.y_pixels) {
|
||||
return HWC2::Error::Unsupported;
|
||||
} else {
|
||||
return HWC2::Error::None;
|
||||
ColorMetaData color_metadata = {};
|
||||
if (dataspace != HAL_DATASPACE_UNKNOWN) {
|
||||
GetColorPrimary(dataspace, &(color_metadata.colorPrimaries));
|
||||
GetTransfer(dataspace, &(color_metadata.transfer));
|
||||
GetRange(dataspace, &(color_metadata.range));
|
||||
}
|
||||
|
||||
LayerBufferFormat sdm_format = GetSDMFormat(format, 0);
|
||||
if (display_intf_->GetClientTargetSupport(width, height, sdm_format,
|
||||
color_metadata) != kErrorNone) {
|
||||
return HWC2::Error::Unsupported;
|
||||
}
|
||||
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
|
||||
|
@ -746,9 +777,18 @@ HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config
|
|||
HWC2::Error HWCDisplay::GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
|
||||
int32_t *out_value) {
|
||||
DisplayConfigVariableInfo variable_config;
|
||||
if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
|
||||
DLOGE("Get variable config failed");
|
||||
return HWC2::Error::BadDisplay;
|
||||
// Get display attributes from config index only if resolution switch is supported.
|
||||
// Otherwise always send mixer attributes. This is to support destination scaler.
|
||||
if (num_configs_ > 1) {
|
||||
if (GetDisplayAttributesForConfig(INT(config), &variable_config) != kErrorNone) {
|
||||
DLOGE("Get variable config failed");
|
||||
return HWC2::Error::BadDisplay;
|
||||
}
|
||||
} else {
|
||||
if (display_intf_->GetFrameBufferConfig(&variable_config) != kErrorNone) {
|
||||
DLOGV("Get variable config failed");
|
||||
return HWC2::Error::BadDisplay;
|
||||
}
|
||||
}
|
||||
|
||||
switch (attribute) {
|
||||
|
@ -847,7 +887,13 @@ HWC2::Error HWCDisplay::SetClientTarget(buffer_handle_t target, int32_t acquire_
|
|||
|
||||
client_target_->SetLayerBuffer(target, acquire_fence);
|
||||
client_target_->SetLayerSurfaceDamage(damage);
|
||||
// Ignoring dataspace for now
|
||||
if (client_target_->GetLayerDataspace() != dataspace) {
|
||||
client_target_->SetLayerDataspace(dataspace);
|
||||
Layer *sdm_layer = client_target_->GetSDMLayer();
|
||||
// Data space would be validated at GetClientTargetSupport, so just use here.
|
||||
sdm::GetSDMColorSpace(dataspace, &sdm_layer->input_buffer.color_metadata);
|
||||
}
|
||||
|
||||
return HWC2::Error::None;
|
||||
}
|
||||
|
||||
|
@ -965,6 +1011,7 @@ HWC2::Error HWCDisplay::PrepareLayerStack(uint32_t *out_num_types, uint32_t *out
|
|||
}
|
||||
hwc_layer->ResetValidation();
|
||||
}
|
||||
client_target_->ResetValidation();
|
||||
*out_num_types = UINT32(layer_changes_.size());
|
||||
*out_num_requests = UINT32(layer_requests_.size());
|
||||
skip_validate_ = false;
|
||||
|
@ -1172,6 +1219,7 @@ HWC2::Error HWCDisplay::PostCommitLayerStack(int32_t *out_retire_fence) {
|
|||
close(client_target_release_fence);
|
||||
client_target_release_fence = -1;
|
||||
}
|
||||
client_target_->ResetGeometryChanges();
|
||||
|
||||
for (auto hwc_layer : layer_set_) {
|
||||
hwc_layer->ResetGeometryChanges();
|
||||
|
@ -1381,6 +1429,7 @@ void HWCDisplay::DumpInputBuffers() {
|
|||
return;
|
||||
}
|
||||
|
||||
DLOGI("dump_frame_count %d dump_input_layers %d", dump_frame_count_, dump_input_layers_);
|
||||
snprintf(dir_path, sizeof(dir_path), "%s/frame_dump_%s", HWCDebugHandler::DumpDir(),
|
||||
GetDisplayString());
|
||||
|
||||
|
@ -1409,22 +1458,43 @@ void HWCDisplay::DumpInputBuffers() {
|
|||
}
|
||||
}
|
||||
|
||||
if (pvt_handle && pvt_handle->base) {
|
||||
char dump_file_name[PATH_MAX];
|
||||
size_t result = 0;
|
||||
DLOGI("Dump layer[%d] of %d pvt_handle %x pvt_handle->base %x", i, layer_stack_.layers.size(),
|
||||
pvt_handle, pvt_handle? pvt_handle->base : 0);
|
||||
|
||||
snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
|
||||
dir_path, i, pvt_handle->width, pvt_handle->height,
|
||||
qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
|
||||
|
||||
FILE *fp = fopen(dump_file_name, "w+");
|
||||
if (fp) {
|
||||
result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
|
||||
if (!pvt_handle) {
|
||||
DLOGE("Buffer handle is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pvt_handle->base) {
|
||||
DisplayError error = buffer_allocator_->MapBuffer(pvt_handle, -1);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to map buffer, error = %d", error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
char dump_file_name[PATH_MAX];
|
||||
size_t result = 0;
|
||||
|
||||
snprintf(dump_file_name, sizeof(dump_file_name), "%s/input_layer%d_%dx%d_%s_frame%d.raw",
|
||||
dir_path, i, pvt_handle->width, pvt_handle->height,
|
||||
qdutils::GetHALPixelFormatString(pvt_handle->format), dump_frame_index_);
|
||||
|
||||
FILE *fp = fopen(dump_file_name, "w+");
|
||||
if (fp) {
|
||||
result = fwrite(reinterpret_cast<void *>(pvt_handle->base), pvt_handle->size, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
int release_fence = -1;
|
||||
DisplayError error = buffer_allocator_->UnmapBuffer(pvt_handle, &release_fence);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to unmap buffer, error = %d", error);
|
||||
return;
|
||||
}
|
||||
|
||||
DLOGI("Frame Dump %s: is %s", dump_file_name, result ? "Successful" : "Failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1519,10 +1589,13 @@ int HWCDisplay::SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels) {
|
|||
int aligned_height;
|
||||
uint32_t usage = GRALLOC_USAGE_HW_FB;
|
||||
int format = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||
int ubwc_enabled = 0;
|
||||
int ubwc_disabled = 0;
|
||||
int flags = 0;
|
||||
HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
|
||||
if (ubwc_enabled == 1) {
|
||||
|
||||
// By default UBWC is enabled and below property is global enable/disable for all
|
||||
// buffers allocated through gralloc , including framebuffer targets.
|
||||
HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
|
||||
if (!ubwc_disabled) {
|
||||
usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
|
||||
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
|
||||
}
|
||||
|
@ -1786,7 +1859,12 @@ int HWCDisplay::GetVisibleDisplayRect(hwc_rect_t *visible_rect) {
|
|||
}
|
||||
|
||||
void HWCDisplay::SetSecureDisplay(bool secure_display_active) {
|
||||
secure_display_active_ = secure_display_active;
|
||||
if (secure_display_active_ != secure_display_active) {
|
||||
DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
|
||||
secure_display_active);
|
||||
secure_display_active_ = secure_display_active;
|
||||
skip_prepare_ = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1918,6 +1996,10 @@ bool HWCDisplay::CanSkipValidate() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (client_target_->NeedsValidation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto hwc_layer : layer_set_) {
|
||||
if (hwc_layer->NeedsValidation()) {
|
||||
return false;
|
||||
|
|
|
@ -62,6 +62,7 @@ class HWCColorMode {
|
|||
HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
|
||||
HWC2::Error SetColorMode(android_color_mode_t mode);
|
||||
HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
|
||||
HWC2::Error RestoreColorTransform();
|
||||
|
||||
private:
|
||||
static const uint32_t kColorTransformMatrixCount = 16;
|
||||
|
@ -172,6 +173,9 @@ class HWCDisplay : public DisplayEventHandler {
|
|||
virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
|
||||
return HWC2::Error::Unsupported;
|
||||
}
|
||||
virtual HWC2::Error RestoreColorTransform() {
|
||||
return HWC2::Error::Unsupported;
|
||||
}
|
||||
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
|
||||
return HWC2::Error::Unsupported;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,750 @@
|
|||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <utils/constants.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/formats.h>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include "hwc_display_external_test.h"
|
||||
#include "hwc_debugger.h"
|
||||
|
||||
#define __CLASS__ "HWCDisplayExternalTest"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
using std::array;
|
||||
|
||||
int HWCDisplayExternalTest::Create(CoreInterface *core_intf,
|
||||
HWCBufferAllocator *buffer_allocator,
|
||||
HWCCallbacks *callbacks,
|
||||
qService::QService *qservice, uint32_t panel_bpp,
|
||||
uint32_t pattern_type, HWCDisplay **hwc_display) {
|
||||
HWCDisplay *hwc_external_test = new HWCDisplayExternalTest(core_intf, buffer_allocator,
|
||||
callbacks, qservice,
|
||||
panel_bpp, pattern_type);
|
||||
|
||||
int status = static_cast<HWCDisplayExternalTest *>(hwc_external_test)->Init();
|
||||
if (status) {
|
||||
delete hwc_external_test;
|
||||
return status;
|
||||
}
|
||||
|
||||
*hwc_display = hwc_external_test;
|
||||
|
||||
DLOGE("EXTERNAL panel_bpp %d, pattern_type %d", panel_bpp, pattern_type);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::Destroy(HWCDisplay *hwc_display) {
|
||||
static_cast<HWCDisplayExternalTest *>(hwc_display)->Deinit();
|
||||
|
||||
delete hwc_display;
|
||||
}
|
||||
|
||||
HWCDisplayExternalTest::HWCDisplayExternalTest(CoreInterface *core_intf,
|
||||
HWCBufferAllocator *buffer_allocator,
|
||||
HWCCallbacks *callbacks,
|
||||
qService::QService *qservice, uint32_t panel_bpp,
|
||||
uint32_t pattern_type)
|
||||
: HWCDisplay(core_intf, callbacks, kHDMI, HWC_DISPLAY_EXTERNAL, false, qservice,
|
||||
DISPLAY_CLASS_EXTERNAL, buffer_allocator), panel_bpp_(panel_bpp),
|
||||
pattern_type_(pattern_type) {
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::Init() {
|
||||
uint32_t external_width = 0;
|
||||
uint32_t external_height = 0;
|
||||
|
||||
int status = HWCDisplay::Init();
|
||||
if (status) {
|
||||
DLOGE("HWCDisplayExternalTest::Init status = %d ", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = CreateLayerStack();
|
||||
if (status) {
|
||||
Deinit();
|
||||
return status;
|
||||
}
|
||||
|
||||
DisplayError error = HWCDisplay::GetMixerResolution(&external_width, &external_height);
|
||||
if (error != kErrorNone) {
|
||||
Deinit();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = HWCDisplay::SetFrameBufferResolution(external_width, external_height);
|
||||
if (status) {
|
||||
Deinit();
|
||||
DLOGE("HWCDisplayExternalTest:: set fb resolution status = %d ", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::Deinit() {
|
||||
DestroyLayerStack();
|
||||
return HWCDisplay::Deinit();
|
||||
}
|
||||
|
||||
|
||||
HWC2::Error HWCDisplayExternalTest::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
|
||||
auto status = HWC2::Error::None;
|
||||
if (secure_display_active_) {
|
||||
MarkLayersForGPUBypass();
|
||||
return status;
|
||||
}
|
||||
|
||||
if (layer_set_.empty()) {
|
||||
flush_ = true;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (shutdown_pending_) {
|
||||
return status;
|
||||
}
|
||||
DisplayError error = display_intf_->Prepare(&layer_stack_);
|
||||
if (error != kErrorNone) {
|
||||
if (error == kErrorShutDown) {
|
||||
shutdown_pending_ = true;
|
||||
} else if (error != kErrorPermission) {
|
||||
DLOGE("Prepare failed. Error = %d", error);
|
||||
// To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
|
||||
// so that previous buffer and fences are released, and override the error.
|
||||
flush_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
MarkLayersForGPUBypass();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
HWC2::Error HWCDisplayExternalTest::Present(int32_t *out_retire_fence) {
|
||||
auto status = HWC2::Error::None;
|
||||
|
||||
if (secure_display_active_) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (shutdown_pending_) {
|
||||
return status;
|
||||
}
|
||||
|
||||
DumpInputBuffer();
|
||||
|
||||
if (!flush_) {
|
||||
DisplayError error = kErrorUndefined;
|
||||
error = display_intf_->Commit(&layer_stack_);
|
||||
if (error == kErrorNone) {
|
||||
// A commit is successfully submitted, start flushing on failure now onwards.
|
||||
flush_on_error_ = true;
|
||||
} else {
|
||||
if (error == kErrorShutDown) {
|
||||
shutdown_pending_ = true;
|
||||
return status;
|
||||
} else if (error != kErrorPermission) {
|
||||
DLOGE("Commit failed. Error = %d", error);
|
||||
// To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
|
||||
// so that previous buffer and fences are released, and override the error.
|
||||
flush_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PostCommit(out_retire_fence);
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::SetSecureDisplay(bool secure_display_active) {
|
||||
if (secure_display_active_ != secure_display_active) {
|
||||
secure_display_active_ = secure_display_active;
|
||||
|
||||
if (secure_display_active_) {
|
||||
DisplayError error = display_intf_->Flush();
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Flush failed. Error = %d", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::Perform(uint32_t operation, ...) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::DumpInputBuffer() {
|
||||
if (!dump_frame_count_ || flush_ || !dump_input_layers_) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *dir_path = "/data/vendor/display/frame_dump_external";
|
||||
uint32_t width = buffer_info_.alloc_buffer_info.aligned_width;
|
||||
uint32_t height = buffer_info_.alloc_buffer_info.aligned_height;
|
||||
string format_str = GetFormatString(buffer_info_.buffer_config.format);
|
||||
|
||||
char *buffer = reinterpret_cast<char *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
buffer_info_.alloc_buffer_info.fd, 0));
|
||||
if (buffer == MAP_FAILED) {
|
||||
DLOGW("mmap failed. err = %d", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mkdir(dir_path, 0777) != 0 && errno != EEXIST) {
|
||||
DLOGW("Failed to create %s directory errno = %d, desc = %s", dir_path, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// if directory exists already, need to explicitly change the permission.
|
||||
if (errno == EEXIST && chmod(dir_path, 0777) != 0) {
|
||||
DLOGW("Failed to change permissions on %s directory", dir_path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
std::stringstream dump_file_name;
|
||||
dump_file_name << dir_path;
|
||||
dump_file_name << "/input_layer_" << width << "x" << height << "_" << format_str << ".raw";
|
||||
|
||||
std::fstream fs;
|
||||
fs.open(dump_file_name.str().c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
|
||||
if (!fs.is_open()) {
|
||||
DLOGI("File open failed %s", dump_file_name.str().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fs.write(buffer, (std::streamsize)buffer_info_.alloc_buffer_info.size);
|
||||
fs.close();
|
||||
|
||||
DLOGI("Frame Dump %s: is successful", dump_file_name.str().c_str());
|
||||
}
|
||||
|
||||
// Dump only once as the content is going to be same for all draw cycles
|
||||
if (dump_frame_count_) {
|
||||
dump_frame_count_ = 0;
|
||||
}
|
||||
|
||||
if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
|
||||
DLOGW("munmap failed. err = %d", errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::CalcCRC(uint32_t color_val, std::bitset<16> *crc_data) {
|
||||
std::bitset<16> color = {};
|
||||
std::bitset<16> temp_crc = {};
|
||||
|
||||
switch (panel_bpp_) {
|
||||
case kDisplayBpp18:
|
||||
color = (color_val & 0xFC) << 8;
|
||||
break;
|
||||
case kDisplayBpp24:
|
||||
color = color_val << 8;
|
||||
break;
|
||||
case kDisplayBpp30:
|
||||
color = color_val << 6;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
temp_crc[15] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^
|
||||
(*crc_data)[4] ^ (*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^
|
||||
(*crc_data)[8] ^ (*crc_data)[9] ^ (*crc_data)[10] ^ (*crc_data)[11] ^
|
||||
(*crc_data)[12] ^ (*crc_data)[14] ^ (*crc_data)[15] ^ color[0] ^ color[1] ^
|
||||
color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^ color[7] ^ color[8] ^
|
||||
color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[14] ^ color[15];
|
||||
|
||||
temp_crc[14] = (*crc_data)[12] ^ (*crc_data)[13] ^ color[12] ^ color[13];
|
||||
temp_crc[13] = (*crc_data)[11] ^ (*crc_data)[12] ^ color[11] ^ color[12];
|
||||
temp_crc[12] = (*crc_data)[10] ^ (*crc_data)[11] ^ color[10] ^ color[11];
|
||||
temp_crc[11] = (*crc_data)[9] ^ (*crc_data)[10] ^ color[9] ^ color[10];
|
||||
temp_crc[10] = (*crc_data)[8] ^ (*crc_data)[9] ^ color[8] ^ color[9];
|
||||
temp_crc[9] = (*crc_data)[7] ^ (*crc_data)[8] ^ color[7] ^ color[8];
|
||||
temp_crc[8] = (*crc_data)[6] ^ (*crc_data)[7] ^ color[6] ^ color[7];
|
||||
temp_crc[7] = (*crc_data)[5] ^ (*crc_data)[6] ^ color[5] ^ color[6];
|
||||
temp_crc[6] = (*crc_data)[4] ^ (*crc_data)[5] ^ color[4] ^ color[5];
|
||||
temp_crc[5] = (*crc_data)[3] ^ (*crc_data)[4] ^ color[3] ^ color[4];
|
||||
temp_crc[4] = (*crc_data)[2] ^ (*crc_data)[3] ^ color[2] ^ color[3];
|
||||
temp_crc[3] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[15] ^ color[1] ^ color[2] ^ color[15];
|
||||
temp_crc[2] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[14] ^ color[0] ^ color[1] ^ color[14];
|
||||
|
||||
temp_crc[1] = (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^ (*crc_data)[5] ^
|
||||
(*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
|
||||
(*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
|
||||
(*crc_data)[14] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^ color[6] ^
|
||||
color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^ color[13] ^
|
||||
color[14];
|
||||
|
||||
temp_crc[0] = (*crc_data)[0] ^ (*crc_data)[1] ^ (*crc_data)[2] ^ (*crc_data)[3] ^ (*crc_data)[4] ^
|
||||
(*crc_data)[5] ^ (*crc_data)[6] ^ (*crc_data)[7] ^ (*crc_data)[8] ^ (*crc_data)[9] ^
|
||||
(*crc_data)[10] ^ (*crc_data)[11] ^ (*crc_data)[12] ^ (*crc_data)[13] ^
|
||||
(*crc_data)[15] ^ color[0] ^ color[1] ^ color[2] ^ color[3] ^ color[4] ^ color[5] ^
|
||||
color[6] ^ color[7] ^ color[8] ^ color[9] ^ color[10] ^ color[11] ^ color[12] ^
|
||||
color[13] ^ color[15];
|
||||
|
||||
(*crc_data) = temp_crc;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::FillBuffer() {
|
||||
uint8_t *buffer = reinterpret_cast<uint8_t *>(mmap(NULL, buffer_info_.alloc_buffer_info.size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
buffer_info_.alloc_buffer_info.fd, 0));
|
||||
if (buffer == MAP_FAILED) {
|
||||
DLOGE("mmap failed. err = %d", errno);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
switch (pattern_type_) {
|
||||
case kPatternColorRamp:
|
||||
GenerateColorRamp(buffer);
|
||||
break;
|
||||
case kPatternBWVertical:
|
||||
GenerateBWVertical(buffer);
|
||||
break;
|
||||
case kPatternColorSquare:
|
||||
GenerateColorSquare(buffer);
|
||||
break;
|
||||
default:
|
||||
DLOGW("Invalid Pattern type %d", pattern_type_);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (munmap(buffer, buffer_info_.alloc_buffer_info.size) != 0) {
|
||||
DLOGE("munmap failed. err = %d", errno);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride) {
|
||||
switch (format) {
|
||||
case kFormatRGBA8888:
|
||||
case kFormatRGBA1010102:
|
||||
*stride = width * 4;
|
||||
break;
|
||||
case kFormatRGB888:
|
||||
*stride = width * 3;
|
||||
break;
|
||||
default:
|
||||
DLOGE("Unsupported format type %d", format);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha,
|
||||
uint8_t **buffer) {
|
||||
LayerBufferFormat format = buffer_info_.buffer_config.format;
|
||||
|
||||
switch (format) {
|
||||
case kFormatRGBA8888:
|
||||
*(*buffer)++ = UINT8(red & 0xFF);
|
||||
*(*buffer)++ = UINT8(green & 0xFF);
|
||||
*(*buffer)++ = UINT8(blue & 0xFF);
|
||||
*(*buffer)++ = UINT8(alpha & 0xFF);
|
||||
break;
|
||||
case kFormatRGB888:
|
||||
*(*buffer)++ = UINT8(red & 0xFF);
|
||||
*(*buffer)++ = UINT8(green & 0xFF);
|
||||
*(*buffer)++ = UINT8(blue & 0xFF);
|
||||
break;
|
||||
case kFormatRGBA1010102:
|
||||
// Lower 8 bits of red
|
||||
*(*buffer)++ = UINT8(red & 0xFF);
|
||||
|
||||
// Upper 2 bits of Red + Lower 6 bits of green
|
||||
*(*buffer)++ = UINT8(((green & 0x3F) << 2) | ((red >> 0x8) & 0x3));
|
||||
|
||||
// Upper 4 bits of green + Lower 4 bits of blue
|
||||
*(*buffer)++ = UINT8(((blue & 0xF) << 4) | ((green >> 6) & 0xF));
|
||||
|
||||
// Upper 6 bits of blue + Lower 2 bits of alpha
|
||||
*(*buffer)++ = UINT8(((alpha & 0x3) << 6) | ((blue >> 4) & 0x3F));
|
||||
break;
|
||||
default:
|
||||
DLOGW("format not supported format = %d", format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::GenerateColorRamp(uint8_t *buffer) {
|
||||
uint32_t width = buffer_info_.buffer_config.width;
|
||||
uint32_t height = buffer_info_.buffer_config.height;
|
||||
LayerBufferFormat format = buffer_info_.buffer_config.format;
|
||||
uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
|
||||
uint32_t buffer_stride = 0;
|
||||
|
||||
uint32_t color_ramp = 0;
|
||||
uint32_t start_color_val = 0;
|
||||
uint32_t step_size = 1;
|
||||
uint32_t ramp_width = 0;
|
||||
uint32_t ramp_height = 0;
|
||||
uint32_t shift_by = 0;
|
||||
|
||||
std::bitset<16> crc_red = {};
|
||||
std::bitset<16> crc_green = {};
|
||||
std::bitset<16> crc_blue = {};
|
||||
|
||||
switch (panel_bpp_) {
|
||||
case kDisplayBpp18:
|
||||
ramp_height = 64;
|
||||
ramp_width = 64;
|
||||
shift_by = 2;
|
||||
break;
|
||||
case kDisplayBpp24:
|
||||
ramp_height = 64;
|
||||
ramp_width = 256;
|
||||
break;
|
||||
case kDisplayBpp30:
|
||||
ramp_height = 32;
|
||||
ramp_width = 256;
|
||||
start_color_val = 0x180;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
GetStride(format, aligned_width, &buffer_stride);
|
||||
|
||||
for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
|
||||
uint32_t color_value = start_color_val;
|
||||
uint8_t *temp = buffer + (loop_height * buffer_stride);
|
||||
|
||||
for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
|
||||
if (color_ramp == kColorRedRamp) {
|
||||
PixelCopy(color_value, 0, 0, 0, &temp);
|
||||
CalcCRC(color_value, &crc_red);
|
||||
CalcCRC(0, &crc_green);
|
||||
CalcCRC(0, &crc_blue);
|
||||
}
|
||||
if (color_ramp == kColorGreenRamp) {
|
||||
PixelCopy(0, color_value, 0, 0, &temp);
|
||||
CalcCRC(0, &crc_red);
|
||||
CalcCRC(color_value, &crc_green);
|
||||
CalcCRC(0, &crc_blue);
|
||||
}
|
||||
if (color_ramp == kColorBlueRamp) {
|
||||
PixelCopy(0, 0, color_value, 0, &temp);
|
||||
CalcCRC(0, &crc_red);
|
||||
CalcCRC(0, &crc_green);
|
||||
CalcCRC(color_value, &crc_blue);
|
||||
}
|
||||
if (color_ramp == kColorWhiteRamp) {
|
||||
PixelCopy(color_value, color_value, color_value, 0, &temp);
|
||||
CalcCRC(color_value, &crc_red);
|
||||
CalcCRC(color_value, &crc_green);
|
||||
CalcCRC(color_value, &crc_blue);
|
||||
}
|
||||
|
||||
color_value = (start_color_val + (((loop_width + 1) % ramp_width) * step_size)) << shift_by;
|
||||
}
|
||||
|
||||
if (panel_bpp_ == kDisplayBpp30 && ((loop_height + 1) % ramp_height) == 0) {
|
||||
if (start_color_val == 0x180) {
|
||||
start_color_val = 0;
|
||||
step_size = 4;
|
||||
} else {
|
||||
start_color_val = 0x180;
|
||||
step_size = 1;
|
||||
color_ramp = (color_ramp + 1) % 4;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((loop_height + 1) % ramp_height) == 0) {
|
||||
color_ramp = (color_ramp + 1) % 4;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGI("CRC red %x", crc_red.to_ulong());
|
||||
DLOGI("CRC green %x", crc_green.to_ulong());
|
||||
DLOGI("CRC blue %x", crc_blue.to_ulong());
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::GenerateBWVertical(uint8_t *buffer) {
|
||||
uint32_t width = buffer_info_.buffer_config.width;
|
||||
uint32_t height = buffer_info_.buffer_config.height;
|
||||
LayerBufferFormat format = buffer_info_.buffer_config.format;
|
||||
uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
|
||||
uint32_t buffer_stride = 0;
|
||||
uint32_t bits_per_component = panel_bpp_ / 3;
|
||||
uint32_t max_color_val = (1 << bits_per_component) - 1;
|
||||
|
||||
std::bitset<16> crc_red = {};
|
||||
std::bitset<16> crc_green = {};
|
||||
std::bitset<16> crc_blue = {};
|
||||
|
||||
if (panel_bpp_ == kDisplayBpp18) {
|
||||
max_color_val <<= 2;
|
||||
}
|
||||
|
||||
GetStride(format, aligned_width, &buffer_stride);
|
||||
|
||||
for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
|
||||
uint32_t color = 0;
|
||||
uint8_t *temp = buffer + (loop_height * buffer_stride);
|
||||
|
||||
for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
|
||||
if (color == kColorBlack) {
|
||||
PixelCopy(0, 0, 0, 0, &temp);
|
||||
CalcCRC(0, &crc_red);
|
||||
CalcCRC(0, &crc_green);
|
||||
CalcCRC(0, &crc_blue);
|
||||
}
|
||||
if (color == kColorWhite) {
|
||||
PixelCopy(max_color_val, max_color_val, max_color_val, 0, &temp);
|
||||
CalcCRC(max_color_val, &crc_red);
|
||||
CalcCRC(max_color_val, &crc_green);
|
||||
CalcCRC(max_color_val, &crc_blue);
|
||||
}
|
||||
|
||||
color = (color + 1) % 2;
|
||||
}
|
||||
}
|
||||
|
||||
DLOGI("CRC red %x", crc_red.to_ulong());
|
||||
DLOGI("CRC green %x", crc_green.to_ulong());
|
||||
DLOGI("CRC blue %x", crc_blue.to_ulong());
|
||||
}
|
||||
|
||||
void HWCDisplayExternalTest::GenerateColorSquare(uint8_t *buffer) {
|
||||
uint32_t width = buffer_info_.buffer_config.width;
|
||||
uint32_t height = buffer_info_.buffer_config.height;
|
||||
LayerBufferFormat format = buffer_info_.buffer_config.format;
|
||||
uint32_t aligned_width = buffer_info_.alloc_buffer_info.aligned_width;
|
||||
uint32_t buffer_stride = 0;
|
||||
uint32_t max_color_val = 0;
|
||||
uint32_t min_color_val = 0;
|
||||
|
||||
std::bitset<16> crc_red = {};
|
||||
std::bitset<16> crc_green = {};
|
||||
std::bitset<16> crc_blue = {};
|
||||
|
||||
switch (panel_bpp_) {
|
||||
case kDisplayBpp18:
|
||||
max_color_val = 63 << 2; // CEA Dynamic range for 18bpp 0 - 63
|
||||
min_color_val = 0;
|
||||
break;
|
||||
case kDisplayBpp24:
|
||||
max_color_val = 235; // CEA Dynamic range for 24bpp 16 - 235
|
||||
min_color_val = 16;
|
||||
break;
|
||||
case kDisplayBpp30:
|
||||
max_color_val = 940; // CEA Dynamic range for 30bpp 64 - 940
|
||||
min_color_val = 64;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
array<array<uint32_t, 3>, 8> colors = {{
|
||||
{{max_color_val, max_color_val, max_color_val}}, // White Color
|
||||
{{max_color_val, max_color_val, min_color_val}}, // Yellow Color
|
||||
{{min_color_val, max_color_val, max_color_val}}, // Cyan Color
|
||||
{{min_color_val, max_color_val, min_color_val}}, // Green Color
|
||||
{{max_color_val, min_color_val, max_color_val}}, // Megenta Color
|
||||
{{max_color_val, min_color_val, min_color_val}}, // Red Color
|
||||
{{min_color_val, min_color_val, max_color_val}}, // Blue Color
|
||||
{{min_color_val, min_color_val, min_color_val}}, // Black Color
|
||||
}};
|
||||
|
||||
GetStride(format, aligned_width, &buffer_stride);
|
||||
|
||||
for (uint32_t loop_height = 0; loop_height < height; loop_height++) {
|
||||
uint32_t color = 0;
|
||||
uint8_t *temp = buffer + (loop_height * buffer_stride);
|
||||
|
||||
for (uint32_t loop_width = 0; loop_width < width; loop_width++) {
|
||||
PixelCopy(colors[color][0], colors[color][1], colors[color][2], 0, &temp);
|
||||
CalcCRC(colors[color][0], &crc_red);
|
||||
CalcCRC(colors[color][1], &crc_green);
|
||||
CalcCRC(colors[color][2], &crc_blue);
|
||||
|
||||
if (((loop_width + 1) % 64) == 0) {
|
||||
color = (color + 1) % colors.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (((loop_height + 1) % 64) == 0) {
|
||||
std::reverse(colors.begin(), (colors.end() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
DLOGI("CRC red %x", crc_red.to_ulong());
|
||||
DLOGI("CRC green %x", crc_green.to_ulong());
|
||||
DLOGI("CRC blue %x", crc_blue.to_ulong());
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::InitLayer(Layer *layer) {
|
||||
uint32_t active_config = 0;
|
||||
DisplayConfigVariableInfo var_info = {};
|
||||
|
||||
GetActiveDisplayConfig(&active_config);
|
||||
|
||||
GetDisplayAttributesForConfig(INT32(active_config), &var_info);
|
||||
|
||||
layer->flags.updating = 1;
|
||||
layer->src_rect = LayerRect(0, 0, var_info.x_pixels, var_info.y_pixels);
|
||||
layer->dst_rect = layer->src_rect;
|
||||
layer->frame_rate = var_info.fps;
|
||||
layer->blending = kBlendingPremultiplied;
|
||||
|
||||
layer->input_buffer.unaligned_width = var_info.x_pixels;
|
||||
layer->input_buffer.unaligned_height = var_info.y_pixels;
|
||||
buffer_info_.buffer_config.format = kFormatRGBA8888;
|
||||
|
||||
if (layer->composition != kCompositionGPUTarget) {
|
||||
buffer_info_.buffer_config.width = var_info.x_pixels;
|
||||
buffer_info_.buffer_config.height = var_info.y_pixels;
|
||||
switch (panel_bpp_) {
|
||||
case kDisplayBpp18:
|
||||
case kDisplayBpp24:
|
||||
buffer_info_.buffer_config.format = kFormatRGB888;
|
||||
break;
|
||||
case kDisplayBpp30:
|
||||
buffer_info_.buffer_config.format = kFormatRGBA1010102;
|
||||
break;
|
||||
default:
|
||||
DLOGW("panel bpp not supported %d", panel_bpp_);
|
||||
return -EINVAL;
|
||||
}
|
||||
buffer_info_.buffer_config.buffer_count = 1;
|
||||
|
||||
int ret = buffer_allocator_->AllocateBuffer(&buffer_info_);
|
||||
if (ret != 0) {
|
||||
DLOGE("Buffer allocation failed. ret: %d", ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = FillBuffer();
|
||||
if (ret != 0) {
|
||||
buffer_allocator_->FreeBuffer(&buffer_info_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
layer->input_buffer.width = buffer_info_.alloc_buffer_info.aligned_width;
|
||||
layer->input_buffer.height = buffer_info_.alloc_buffer_info.aligned_height;
|
||||
layer->input_buffer.size = buffer_info_.alloc_buffer_info.size;
|
||||
layer->input_buffer.planes[0].fd = buffer_info_.alloc_buffer_info.fd;
|
||||
layer->input_buffer.planes[0].stride = buffer_info_.alloc_buffer_info.stride;
|
||||
layer->input_buffer.format = buffer_info_.buffer_config.format;
|
||||
|
||||
DLOGI("Input buffer WxH %dx%d format %s size %d fd %d stride %d", layer->input_buffer.width,
|
||||
layer->input_buffer.height, GetFormatString(layer->input_buffer.format),
|
||||
layer->input_buffer.size, layer->input_buffer.planes[0].fd,
|
||||
layer->input_buffer.planes[0].stride);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::DeinitLayer(Layer *layer) {
|
||||
if (layer->composition != kCompositionGPUTarget) {
|
||||
int ret = buffer_allocator_->FreeBuffer(&buffer_info_);
|
||||
if (ret != 0) {
|
||||
DLOGE("Buffer deallocation failed. ret: %d", ret);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::CreateLayerStack() {
|
||||
for (uint32_t i = 0; i < (kTestLayerCnt + 1 /* one dummy gpu_target layer */); i++) {
|
||||
Layer *layer = new Layer();
|
||||
|
||||
if (i == kTestLayerCnt) {
|
||||
layer->composition = kCompositionGPUTarget;
|
||||
}
|
||||
DLOGE("External :: CreateLayerStack %d", i);
|
||||
int ret = InitLayer(layer);
|
||||
if (ret != 0) {
|
||||
delete layer;
|
||||
return ret;
|
||||
}
|
||||
layer_stack_.layers.push_back(layer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HWCDisplayExternalTest::DestroyLayerStack() {
|
||||
for (uint32_t i = 0; i < UINT32(layer_stack_.layers.size()); i++) {
|
||||
Layer *layer = layer_stack_.layers.at(i);
|
||||
int ret = DeinitLayer(layer);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
delete layer;
|
||||
}
|
||||
layer_stack_.layers = {};
|
||||
return 0;
|
||||
}
|
||||
|
||||
HWC2::Error HWCDisplayExternalTest::PostCommit(int32_t *out_retire_fence) {
|
||||
auto status = HWC2::Error::None;
|
||||
// Do no call flush on errors, if a successful buffer is never submitted.
|
||||
if (flush_ && flush_on_error_) {
|
||||
display_intf_->Flush();
|
||||
}
|
||||
if (!flush_) {
|
||||
for (size_t i = 0; i < layer_stack_.layers.size(); i++) {
|
||||
Layer *layer = layer_stack_.layers.at(i);
|
||||
LayerBuffer &layer_buffer = layer->input_buffer;
|
||||
|
||||
close(layer_buffer.release_fence_fd);
|
||||
layer_buffer.release_fence_fd = -1;
|
||||
}
|
||||
close(layer_stack_.retire_fence_fd);
|
||||
layer_stack_.retire_fence_fd = -1;
|
||||
*out_retire_fence = -1;
|
||||
}
|
||||
|
||||
flush_ = false;
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
* provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
|
||||
* endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HWC_DISPLAY_EXTERNAL_TEST_H__
|
||||
#define __HWC_DISPLAY_EXTERNAL_TEST_H__
|
||||
|
||||
#include<bitset>
|
||||
|
||||
#include "hwc_display.h"
|
||||
#include "hwc_buffer_allocator.h"
|
||||
|
||||
namespace sdm {
|
||||
|
||||
class HWCDisplayExternalTest : public HWCDisplay {
|
||||
public:
|
||||
static int Create(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
|
||||
HWCCallbacks *callbacks, qService::QService *qservice,
|
||||
uint32_t panel_bpp, uint32_t pattern_type, HWCDisplay **hwc_display);
|
||||
static void Destroy(HWCDisplay *hwc_display);
|
||||
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
|
||||
virtual HWC2::Error Present(int32_t *out_retire_fence);
|
||||
virtual void SetSecureDisplay(bool secure_display_active);
|
||||
virtual int Perform(uint32_t operation, ...);
|
||||
|
||||
protected:
|
||||
BufferInfo buffer_info_ = {};
|
||||
uint32_t panel_bpp_ = 0;
|
||||
uint32_t pattern_type_ = 0;
|
||||
|
||||
enum ColorPatternType {
|
||||
kPatternNone = 0,
|
||||
kPatternColorRamp,
|
||||
kPatternBWVertical,
|
||||
kPatternColorSquare,
|
||||
};
|
||||
|
||||
enum DisplayBpp {
|
||||
kDisplayBpp18 = 18,
|
||||
kDisplayBpp24 = 24,
|
||||
kDisplayBpp30 = 30,
|
||||
};
|
||||
|
||||
enum ColorRamp {
|
||||
kColorRedRamp = 0,
|
||||
kColorGreenRamp = 1,
|
||||
kColorBlueRamp = 2,
|
||||
kColorWhiteRamp = 3,
|
||||
};
|
||||
|
||||
enum Colors {
|
||||
kColorBlack = 0,
|
||||
kColorWhite = 1,
|
||||
};
|
||||
|
||||
private:
|
||||
HWCDisplayExternalTest(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
|
||||
HWCCallbacks *callbacks, qService::QService *qservice,
|
||||
uint32_t panel_bpp, uint32_t pattern_type);
|
||||
int Init();
|
||||
int Deinit();
|
||||
void DumpInputBuffer();
|
||||
void CalcCRC(uint32_t color_value, std::bitset<16> *crc_data);
|
||||
int FillBuffer();
|
||||
int GetStride(LayerBufferFormat format, uint32_t width, uint32_t *stride);
|
||||
void PixelCopy(uint32_t red, uint32_t green, uint32_t blue, uint32_t alpha, uint8_t **buffer);
|
||||
void GenerateColorRamp(uint8_t *buffer);
|
||||
void GenerateBWVertical(uint8_t *buffer);
|
||||
void GenerateColorSquare(uint8_t *buffer);
|
||||
int InitLayer(Layer *layer);
|
||||
int DeinitLayer(Layer *layer);
|
||||
int CreateLayerStack();
|
||||
int DestroyLayerStack();
|
||||
HWC2::Error PostCommit(int32_t *out_retire_fence);
|
||||
|
||||
static const uint32_t kTestLayerCnt = 1;
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __HWC_DISPLAY_EXTERNAL_TEST_H__
|
||||
|
|
@ -153,8 +153,10 @@ void HWCDisplayPrimary::ProcessBootAnimCompleted() {
|
|||
boot_animation_completed_ = true;
|
||||
// Applying default mode after bootanimation is finished And
|
||||
// If Data is Encrypted, it is ready for access.
|
||||
if (display_intf_)
|
||||
if (display_intf_) {
|
||||
display_intf_->ApplyDefaultDisplayMode();
|
||||
RestoreColorTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +269,18 @@ HWC2::Error HWCDisplayPrimary::SetColorMode(android_color_mode_t mode) {
|
|||
return status;
|
||||
}
|
||||
|
||||
HWC2::Error HWCDisplayPrimary::RestoreColorTransform() {
|
||||
auto status = color_mode_->RestoreColorTransform();
|
||||
if (status != HWC2::Error::None) {
|
||||
DLOGE("failed to RestoreColorTransform");
|
||||
return status;
|
||||
}
|
||||
|
||||
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
HWC2::Error HWCDisplayPrimary::SetColorTransform(const float *matrix,
|
||||
android_color_transform_t hint) {
|
||||
if (!matrix) {
|
||||
|
@ -372,9 +386,12 @@ void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active) {
|
|||
DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
|
||||
secure_display_active);
|
||||
secure_display_active_ = secure_display_active;
|
||||
skip_prepare_ = true;
|
||||
|
||||
// Avoid flush for Command mode panel.
|
||||
DisplayConfigFixedInfo display_config;
|
||||
display_intf_->GetConfig(&display_config);
|
||||
skip_prepare_ = !display_config.is_cmdmode;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
|
||||
|
|
|
@ -58,6 +58,7 @@ class HWCDisplayPrimary : public HWCDisplay {
|
|||
virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
|
||||
virtual HWC2::Error SetColorMode(android_color_mode_t mode);
|
||||
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
|
||||
virtual HWC2::Error RestoreColorTransform();
|
||||
virtual int Perform(uint32_t operation, ...);
|
||||
virtual void SetSecureDisplay(bool secure_display_active);
|
||||
virtual DisplayError Refresh();
|
||||
|
|
|
@ -123,6 +123,11 @@ HWC2::Error HWCDisplayVirtual::Validate(uint32_t *out_num_types, uint32_t *out_n
|
|||
|
||||
BuildLayerStack();
|
||||
layer_stack_.output_buffer = output_buffer_;
|
||||
|
||||
if (layer_set_.empty()) {
|
||||
DLOGI("Skipping Validate and Commit");
|
||||
return status;
|
||||
}
|
||||
status = PrepareLayerStack(out_num_types, out_num_requests);
|
||||
return status;
|
||||
}
|
||||
|
@ -139,10 +144,18 @@ HWC2::Error HWCDisplayVirtual::Present(int32_t *out_retire_fence) {
|
|||
status = HWCDisplay::CommitLayerStack();
|
||||
if (status == HWC2::Error::None) {
|
||||
if (dump_frame_count_ && !flush_ && dump_output_layer_) {
|
||||
if (output_handle_ && output_handle_->base) {
|
||||
if (output_handle_) {
|
||||
BufferInfo buffer_info;
|
||||
const private_handle_t *output_handle =
|
||||
reinterpret_cast<const private_handle_t *>(output_buffer_->buffer_id);
|
||||
DisplayError error = kErrorNone;
|
||||
if (!output_handle->base) {
|
||||
error = buffer_allocator_->MapBuffer(output_handle, -1);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to map output buffer, error = %d", error);
|
||||
return HWC2::Error::BadParameter;
|
||||
}
|
||||
}
|
||||
buffer_info.buffer_config.width = static_cast<uint32_t>(output_handle->width);
|
||||
buffer_info.buffer_config.height = static_cast<uint32_t>(output_handle->height);
|
||||
buffer_info.buffer_config.format =
|
||||
|
@ -150,6 +163,13 @@ HWC2::Error HWCDisplayVirtual::Present(int32_t *out_retire_fence) {
|
|||
buffer_info.alloc_buffer_info.size = static_cast<uint32_t>(output_handle->size);
|
||||
DumpOutputBuffer(buffer_info, reinterpret_cast<void *>(output_handle->base),
|
||||
layer_stack_.retire_fence_fd);
|
||||
|
||||
int release_fence = -1;
|
||||
error = buffer_allocator_->UnmapBuffer(output_handle, &release_fence);
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Failed to unmap buffer, error = %d", error);
|
||||
return HWC2::Error::BadParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,105 @@ DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_met
|
|||
return kErrorNone;
|
||||
}
|
||||
|
||||
// Returns true when color primary is supported
|
||||
bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary) {
|
||||
auto standard = dataspace & HAL_DATASPACE_STANDARD_MASK;
|
||||
bool supported_csc = true;
|
||||
switch (standard) {
|
||||
case HAL_DATASPACE_STANDARD_BT709:
|
||||
*color_primary = ColorPrimaries_BT709_5;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT601_525:
|
||||
case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
|
||||
*color_primary = ColorPrimaries_BT601_6_525;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT601_625:
|
||||
case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
|
||||
*color_primary = ColorPrimaries_BT601_6_625;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_DCI_P3:
|
||||
*color_primary = ColorPrimaries_DCIP3;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT2020:
|
||||
*color_primary = ColorPrimaries_BT2020;
|
||||
break;
|
||||
default:
|
||||
DLOGV_IF(kTagStrategy, "Unsupported Standard Request = %d", standard);
|
||||
supported_csc = false;
|
||||
}
|
||||
return supported_csc;
|
||||
}
|
||||
|
||||
bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer) {
|
||||
auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK;
|
||||
bool supported_transfer = true;
|
||||
switch (transfer) {
|
||||
case HAL_DATASPACE_TRANSFER_SRGB:
|
||||
*gamma_transfer = Transfer_sRGB;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_SMPTE_170M:
|
||||
*gamma_transfer = Transfer_SMPTE_170M;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_ST2084:
|
||||
*gamma_transfer = Transfer_SMPTE_ST2084;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_HLG:
|
||||
*gamma_transfer = Transfer_HLG;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_LINEAR:
|
||||
*gamma_transfer = Transfer_Linear;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_GAMMA2_2:
|
||||
*gamma_transfer = Transfer_Gamma2_2;
|
||||
break;
|
||||
default:
|
||||
DLOGV_IF(kTagStrategy, "Unsupported Transfer Request = %d", transfer);
|
||||
supported_transfer = false;
|
||||
}
|
||||
return supported_transfer;
|
||||
}
|
||||
|
||||
void GetRange(const int32_t &dataspace, ColorRange *color_range) {
|
||||
auto range = dataspace & HAL_DATASPACE_RANGE_MASK;
|
||||
switch (range) {
|
||||
case HAL_DATASPACE_RANGE_FULL:
|
||||
*color_range = Range_Full;
|
||||
break;
|
||||
case HAL_DATASPACE_RANGE_LIMITED:
|
||||
*color_range = Range_Limited;
|
||||
break;
|
||||
default:
|
||||
DLOGV_IF(kTagStrategy, "Unsupported Range Request = %d", range);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBT2020(const ColorPrimaries &color_primary) {
|
||||
switch (color_primary) {
|
||||
case ColorPrimaries_BT2020:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve ColorMetaData from android_data_space_t (STANDARD|TRANSFER|RANGE)
|
||||
bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata) {
|
||||
bool valid = false;
|
||||
valid = GetColorPrimary(dataspace, &(color_metadata->colorPrimaries));
|
||||
if (!valid) {
|
||||
return valid;
|
||||
}
|
||||
valid = GetTransfer(dataspace, &(color_metadata->transfer));
|
||||
if (!valid) {
|
||||
return valid;
|
||||
}
|
||||
GetRange(dataspace, &(color_metadata->range));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Layer operations
|
||||
HWCLayer::HWCLayer(hwc2_display_t display_id, HWCBufferAllocator *buf_allocator)
|
||||
: id_(next_id_++), display_id_(display_id), buffer_allocator_(buf_allocator) {
|
||||
|
@ -270,6 +369,7 @@ HWC2::Error HWCLayer::SetLayerDataspace(int32_t dataspace) {
|
|||
}
|
||||
}
|
||||
|
||||
// cache the dataspace, to be used later to update SDM ColorMetaData
|
||||
if (dataspace_ != dataspace) {
|
||||
geometry_changes_ |= kDataspace;
|
||||
dataspace_ = dataspace;
|
||||
|
@ -559,19 +659,6 @@ LayerBufferS3DFormat HWCLayer::GetS3DFormat(uint32_t s3d_format) {
|
|||
|
||||
DisplayError HWCLayer::SetMetaData(const private_handle_t *pvt_handle, Layer *layer) {
|
||||
LayerBuffer *layer_buffer = &layer->input_buffer;
|
||||
bool use_color_metadata = true;
|
||||
|
||||
#ifdef FEATURE_WIDE_COLOR
|
||||
// Only use color metadata if Android framework metadata is not set
|
||||
use_color_metadata = (dataspace_ == HAL_DATASPACE_UNKNOWN);
|
||||
#endif
|
||||
|
||||
if (use_color_metadata) {
|
||||
if (sdm::SetCSC(pvt_handle, &layer_buffer->color_metadata) != kErrorNone) {
|
||||
return kErrorNotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
private_handle_t *handle = const_cast<private_handle_t *>(pvt_handle);
|
||||
IGC_t igc = {};
|
||||
LayerIGC layer_igc = layer_buffer->igc;
|
||||
|
@ -643,84 +730,44 @@ bool HWCLayer::SupportLocalConversion(ColorPrimaries working_primaries) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool HWCLayer::SupportedDataspace() {
|
||||
if (dataspace_ == HAL_DATASPACE_UNKNOWN) {
|
||||
// Pick values from metadata
|
||||
bool HWCLayer::ValidateAndSetCSC() {
|
||||
if (client_requested_ != HWC2::Composition::Device &&
|
||||
client_requested_ != HWC2::Composition::Cursor) {
|
||||
// Check the layers which are configured to Device
|
||||
return true;
|
||||
}
|
||||
|
||||
LayerBuffer *layer_buffer = &layer_->input_buffer;
|
||||
|
||||
GammaTransfer sdm_transfer = {};
|
||||
ColorPrimaries sdm_primaries = {};
|
||||
ColorRange sdm_range = {};
|
||||
|
||||
auto transfer = dataspace_ & HAL_DATASPACE_TRANSFER_MASK;
|
||||
// Handle transfer
|
||||
switch (transfer) {
|
||||
case HAL_DATASPACE_TRANSFER_SRGB:
|
||||
sdm_transfer = Transfer_sRGB;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_SMPTE_170M:
|
||||
sdm_transfer = Transfer_SMPTE_170M;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_ST2084:
|
||||
sdm_transfer = Transfer_SMPTE_ST2084;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_HLG:
|
||||
sdm_transfer = Transfer_HLG;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_LINEAR:
|
||||
sdm_transfer = Transfer_Linear;
|
||||
break;
|
||||
case HAL_DATASPACE_TRANSFER_GAMMA2_2:
|
||||
sdm_transfer = Transfer_Gamma2_2;
|
||||
break;
|
||||
default:
|
||||
bool use_color_metadata = true;
|
||||
#ifdef FEATURE_WIDE_COLOR
|
||||
ColorMetaData csc = {};
|
||||
if (dataspace_ != HAL_DATASPACE_UNKNOWN) {
|
||||
use_color_metadata = false;
|
||||
bool valid_csc = GetSDMColorSpace(dataspace_, &csc);
|
||||
if (!valid_csc) {
|
||||
return false;
|
||||
}
|
||||
// if we are here here, update the sdm layer csc.
|
||||
layer_buffer->color_metadata.transfer = csc.transfer;
|
||||
layer_buffer->color_metadata.colorPrimaries = csc.colorPrimaries;
|
||||
layer_buffer->color_metadata.range = csc.range;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsBT2020(layer_buffer->color_metadata.colorPrimaries)) {
|
||||
// android_dataspace_t doesnt support mastering display and light levels
|
||||
// so retrieve it from metadata for BT2020(HDR)
|
||||
use_color_metadata = true;
|
||||
}
|
||||
|
||||
// Handle standard
|
||||
auto standard = dataspace_ & HAL_DATASPACE_STANDARD_MASK;
|
||||
switch (standard) {
|
||||
case HAL_DATASPACE_STANDARD_BT709:
|
||||
sdm_primaries = ColorPrimaries_BT709_5;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT601_525:
|
||||
case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
|
||||
sdm_primaries = ColorPrimaries_BT601_6_525;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT601_625:
|
||||
case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
|
||||
sdm_primaries = ColorPrimaries_BT601_6_625;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_DCI_P3:
|
||||
sdm_primaries = ColorPrimaries_DCIP3;
|
||||
break;
|
||||
case HAL_DATASPACE_STANDARD_BT2020:
|
||||
sdm_primaries = ColorPrimaries_BT2020;
|
||||
break;
|
||||
default:
|
||||
if (use_color_metadata) {
|
||||
const private_handle_t *handle =
|
||||
reinterpret_cast<const private_handle_t *>(layer_buffer->buffer_id);
|
||||
if (sdm::SetCSC(handle, &layer_buffer->color_metadata) != kErrorNone) {
|
||||
return false;
|
||||
}
|
||||
// TODO(user): Check transfer + primary combination
|
||||
|
||||
// Handle range
|
||||
auto range = dataspace_ & HAL_DATASPACE_RANGE_MASK;
|
||||
switch (range) {
|
||||
case HAL_DATASPACE_RANGE_FULL:
|
||||
sdm_range = Range_Full;
|
||||
break;
|
||||
case HAL_DATASPACE_RANGE_LIMITED:
|
||||
default:
|
||||
sdm_range = Range_Limited;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, the value is supported, update the layer
|
||||
layer_buffer->color_metadata.transfer = sdm_transfer;
|
||||
layer_buffer->color_metadata.colorPrimaries = sdm_primaries;
|
||||
layer_buffer->color_metadata.range = sdm_range;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,11 @@
|
|||
namespace sdm {
|
||||
|
||||
DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata);
|
||||
|
||||
bool GetColorPrimary(const int32_t &dataspace, ColorPrimaries *color_primary);
|
||||
bool GetTransfer(const int32_t &dataspace, GammaTransfer *gamma_transfer);
|
||||
void GetRange(const int32_t &dataspace, ColorRange *color_range);
|
||||
bool GetSDMColorSpace(const int32_t &dataspace, ColorMetaData *color_metadata);
|
||||
bool IsBT2020(const ColorPrimaries &color_primary);
|
||||
enum GeometryChanges {
|
||||
kNone = 0x000,
|
||||
kBlendMode = 0x001,
|
||||
|
@ -85,7 +89,7 @@ class HWCLayer {
|
|||
void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
|
||||
void PushReleaseFence(int32_t fence);
|
||||
int32_t PopReleaseFence(void);
|
||||
bool SupportedDataspace();
|
||||
bool ValidateAndSetCSC();
|
||||
bool SupportLocalConversion(ColorPrimaries working_primaries);
|
||||
void ResetValidation() { needs_validate_ = false; }
|
||||
bool NeedsValidation() { return (needs_validate_ || geometry_changes_); }
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <utils/constants.h>
|
||||
#include <utils/String16.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <bfqio/bfqio.h>
|
||||
#include <hardware_legacy/uevent.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/prctl.h>
|
||||
|
@ -44,6 +45,8 @@
|
|||
#include "hwc_debugger.h"
|
||||
#include "hwc_display_primary.h"
|
||||
#include "hwc_display_virtual.h"
|
||||
#include "hwc_display_external_test.h"
|
||||
#include "qd_utils.h"
|
||||
|
||||
#define __CLASS__ "HWCSession"
|
||||
|
||||
|
@ -69,13 +72,14 @@ hwc_module_t HAL_MODULE_INFO_SYM = {
|
|||
namespace sdm {
|
||||
|
||||
static HWCUEvent g_hwc_uevent_;
|
||||
Locker HWCSession::locker_;
|
||||
Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
|
||||
|
||||
void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
|
||||
const char *uevent_thread_name = "HWC_UeventThread";
|
||||
|
||||
prctl(PR_SET_NAME, uevent_thread_name, 0, 0, 0);
|
||||
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
|
||||
android_set_rt_ioprio(0, 1);
|
||||
|
||||
int status = uevent_init();
|
||||
if (!status) {
|
||||
|
@ -134,6 +138,8 @@ HWCSession::HWCSession(const hw_module_t *module) {
|
|||
}
|
||||
|
||||
int HWCSession::Init() {
|
||||
SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
int status = -EINVAL;
|
||||
const char *qservice_name = "display.qservice";
|
||||
|
||||
|
@ -156,10 +162,16 @@ int HWCSession::Init() {
|
|||
|
||||
StartServices();
|
||||
|
||||
DisplayError error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
|
||||
&buffer_sync_handler_, &socket_handler_,
|
||||
&core_intf_);
|
||||
DisplayError error = buffer_allocator_.Init();
|
||||
if (error != kErrorNone) {
|
||||
DLOGE("Buffer allocaor initialization failed. Error = %d", error);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = CoreInterface::CreateCore(HWCDebugHandler::Get(), &buffer_allocator_,
|
||||
&buffer_sync_handler_, &socket_handler_, &core_intf_);
|
||||
if (error != kErrorNone) {
|
||||
buffer_allocator_.Deinit();
|
||||
DLOGE("Display core initialization failed. Error = %d", error);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -172,6 +184,7 @@ int HWCSession::Init() {
|
|||
if (error != kErrorNone) {
|
||||
g_hwc_uevent_.Register(nullptr);
|
||||
CoreInterface::DestroyCore();
|
||||
buffer_allocator_.Deinit();
|
||||
DLOGE("Primary display type not recognized. Error = %d", error);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -181,8 +194,7 @@ int HWCSession::Init() {
|
|||
hdmi_is_primary_ = true;
|
||||
// Create display if it is connected, else wait for hotplug connect event.
|
||||
if (hw_disp_info.is_connected) {
|
||||
status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, qservice_,
|
||||
&hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
|
||||
}
|
||||
} else {
|
||||
// Create and power on primary display
|
||||
|
@ -197,6 +209,7 @@ int HWCSession::Init() {
|
|||
if (status) {
|
||||
g_hwc_uevent_.Register(nullptr);
|
||||
CoreInterface::DestroyCore();
|
||||
buffer_allocator_.Deinit();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -214,6 +227,10 @@ int HWCSession::Init() {
|
|||
}
|
||||
|
||||
int HWCSession::Deinit() {
|
||||
Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
|
||||
if (primary_display) {
|
||||
if (hdmi_is_primary_) {
|
||||
|
@ -239,8 +256,6 @@ int HWCSession::Deinit() {
|
|||
}
|
||||
|
||||
int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (!module || !name || !device) {
|
||||
DLOGE("Invalid parameters.");
|
||||
return -EINVAL;
|
||||
|
@ -265,8 +280,6 @@ int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **
|
|||
}
|
||||
|
||||
int HWCSession::Close(hw_device_t *device) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (!device) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -281,6 +294,10 @@ int HWCSession::Close(hw_device_t *device) {
|
|||
|
||||
void HWCSession::GetCapabilities(struct hwc2_device *device, uint32_t *outCount,
|
||||
int32_t *outCapabilities) {
|
||||
if (!outCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
bool disable_skip_validate = false;
|
||||
if (Debug::Get()->GetProperty("sdm.debug.disable_skip_validate", &value) == kErrorNone) {
|
||||
|
@ -307,24 +324,37 @@ static hwc2_function_pointer_t AsFP(T function) {
|
|||
// Defined in the same order as in the HWC2 header
|
||||
|
||||
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (display >= HWC_NUM_DISPLAY_TYPES) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
|
||||
}
|
||||
|
||||
int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t *out_layer_id) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (!out_layer_id) {
|
||||
return HWC2_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
if (display >= HWC_NUM_DISPLAY_TYPES) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
|
||||
return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
|
||||
}
|
||||
|
||||
int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
|
||||
int32_t *format, hwc2_display_t *out_display_id) {
|
||||
// TODO(user): Handle concurrency with HDMI
|
||||
SCOPE_LOCK(locker_);
|
||||
SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
if (!device) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
|
||||
if (!out_display_id || !width || !height || !format) {
|
||||
return HWC2_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
HWCSession *hwc_session = static_cast<HWCSession *>(device);
|
||||
auto status = hwc_session->CreateVirtualDisplayObject(width, height, format);
|
||||
if (status == HWC2::Error::None) {
|
||||
|
@ -339,16 +369,19 @@ int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width,
|
|||
|
||||
int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t layer) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (display >= HWC_NUM_DISPLAY_TYPES) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
|
||||
return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
|
||||
}
|
||||
|
||||
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (!device || display != HWC_DISPLAY_VIRTUAL) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
DLOGI("Destroying virtual display id:%" PRIu64, display);
|
||||
auto *hwc_session = static_cast<HWCSession *>(device);
|
||||
|
||||
|
@ -362,9 +395,7 @@ int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t
|
|||
}
|
||||
|
||||
void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (!device) {
|
||||
if (!device || !out_size) {
|
||||
return;
|
||||
}
|
||||
auto *hwc_session = static_cast<HWCSession *>(device);
|
||||
|
@ -377,6 +408,7 @@ void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffe
|
|||
DumpInterface::GetDump(sdm_dump, 4096); // TODO(user): Fix this workaround
|
||||
std::string s("");
|
||||
for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[id]);
|
||||
if (hwc_session->hwc_display_[id]) {
|
||||
s += hwc_session->hwc_display_[id]->Dump();
|
||||
}
|
||||
|
@ -395,6 +427,10 @@ static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
|
|||
static int32_t GetChangedCompositionTypes(hwc2_device_t *device, hwc2_display_t display,
|
||||
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
|
||||
int32_t *out_types) {
|
||||
// null_ptr check only for out_num_elements, as out_layers and out_types can be null.
|
||||
if (!out_num_elements) {
|
||||
return HWC2_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetChangedCompositionTypes,
|
||||
out_num_elements, out_layers, out_types);
|
||||
}
|
||||
|
@ -479,18 +515,38 @@ static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
|
|||
int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
|
||||
int32_t *out_retire_fence) {
|
||||
HWCSession *hwc_session = static_cast<HWCSession *>(device);
|
||||
bool notify_hotplug = false;
|
||||
auto status = HWC2::Error::BadDisplay;
|
||||
DTRACE_SCOPED();
|
||||
if (!device) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
{
|
||||
SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
|
||||
if (!device) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
|
||||
// TODO(user): Handle virtual display/HDMI concurrency
|
||||
if (hwc_session->hwc_display_[display]) {
|
||||
status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
|
||||
// This is only indicative of how many times SurfaceFlinger posts
|
||||
// frames to the display.
|
||||
CALC_FPS();
|
||||
}
|
||||
}
|
||||
// Handle Pending external display connection
|
||||
if (hwc_session->external_pending_connect_ && (display == HWC_DISPLAY_PRIMARY)) {
|
||||
Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
|
||||
if (!hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
|
||||
DLOGD("Process pending external display connection");
|
||||
hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
|
||||
hwc_session->external_pending_connect_ = false;
|
||||
notify_hotplug = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto status = HWC2::Error::BadDisplay;
|
||||
// TODO(user): Handle virtual display/HDMI concurrency
|
||||
if (hwc_session->hwc_display_[display]) {
|
||||
status = hwc_session->hwc_display_[display]->Present(out_retire_fence);
|
||||
// This is only indicative of how many times SurfaceFlinger posts
|
||||
// frames to the display.
|
||||
CALC_FPS();
|
||||
if (notify_hotplug) {
|
||||
hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
|
||||
}
|
||||
|
||||
return INT32(status);
|
||||
|
@ -508,10 +564,11 @@ int32_t HWCSession::RegisterCallback(hwc2_device_t *device, int32_t descriptor,
|
|||
auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
|
||||
DLOGD("Registering callback: %s", to_string(desc).c_str());
|
||||
if (descriptor == HWC2_CALLBACK_HOTPLUG) {
|
||||
if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY] && !hwc_session->hdmi_is_primary_) {
|
||||
if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
|
||||
}
|
||||
}
|
||||
hwc_session->need_invalidate_ = false;
|
||||
hwc_session->callbacks_lock_.Broadcast();
|
||||
return INT32(error);
|
||||
}
|
||||
|
@ -531,14 +588,14 @@ static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
|
|||
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
|
||||
int32_t /*android_color_mode_t*/ int_mode) {
|
||||
auto mode = static_cast<android_color_mode_t>(int_mode);
|
||||
SCOPE_LOCK(locker_);
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
|
||||
}
|
||||
|
||||
int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
|
||||
const float *matrix,
|
||||
int32_t /*android_color_transform_t*/ hint) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
|
||||
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
|
||||
transform_hint);
|
||||
|
@ -624,7 +681,7 @@ static int32_t SetLayerVisibleRegion(hwc2_device_t *device, hwc2_display_t displ
|
|||
|
||||
int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t layer, uint32_t z) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
|
||||
}
|
||||
|
||||
|
@ -638,6 +695,7 @@ int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t displa
|
|||
return HWC2_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SCOPE_LOCK(locker_[display]);
|
||||
auto *hwc_session = static_cast<HWCSession *>(device);
|
||||
if (hwc_session->hwc_display_[display]) {
|
||||
auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
|
||||
|
@ -650,7 +708,7 @@ int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t displa
|
|||
|
||||
int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
|
||||
auto mode = static_cast<HWC2::PowerMode>(int_mode);
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
|
||||
return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
|
||||
}
|
||||
|
||||
|
@ -662,7 +720,6 @@ static int32_t SetVsyncEnabled(hwc2_device_t *device, hwc2_display_t display, in
|
|||
int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
|
||||
uint32_t *out_num_types, uint32_t *out_num_requests) {
|
||||
DTRACE_SCOPED();
|
||||
SCOPE_LOCK(locker_);
|
||||
HWCSession *hwc_session = static_cast<HWCSession *>(device);
|
||||
if (!device) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
|
@ -671,32 +728,36 @@ int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t displa
|
|||
// TODO(user): Handle secure session, handle QDCM solid fill
|
||||
// Handle external_pending_connect_ in CreateVirtualDisplay
|
||||
auto status = HWC2::Error::BadDisplay;
|
||||
if (hwc_session->hwc_display_[display]) {
|
||||
if (display == HWC_DISPLAY_PRIMARY) {
|
||||
// TODO(user): This can be moved to HWCDisplayPrimary
|
||||
if (hwc_session->reset_panel_) {
|
||||
DLOGW("panel is in bad state, resetting the panel");
|
||||
hwc_session->ResetPanel();
|
||||
{
|
||||
SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
|
||||
if (hwc_session->hwc_display_[display]) {
|
||||
if (display == HWC_DISPLAY_PRIMARY) {
|
||||
// TODO(user): This can be moved to HWCDisplayPrimary
|
||||
if (hwc_session->reset_panel_) {
|
||||
DLOGW("panel is in bad state, resetting the panel");
|
||||
hwc_session->ResetPanel();
|
||||
}
|
||||
|
||||
if (hwc_session->need_invalidate_) {
|
||||
hwc_session->Refresh(display);
|
||||
hwc_session->need_invalidate_ = false;
|
||||
}
|
||||
|
||||
if (hwc_session->color_mgr_) {
|
||||
hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
|
||||
}
|
||||
}
|
||||
|
||||
if (hwc_session->need_invalidate_) {
|
||||
hwc_session->Refresh(display);
|
||||
}
|
||||
|
||||
if (hwc_session->color_mgr_) {
|
||||
hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
|
||||
}
|
||||
}
|
||||
|
||||
status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
|
||||
// Handle pending external display connection
|
||||
if (hwc_session->external_pending_connect_ && !hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
|
||||
DLOGE("Process pending external display connection");
|
||||
hwc_session->ConnectDisplay(HWC_DISPLAY_EXTERNAL);
|
||||
hwc_session->external_pending_connect_ = false;
|
||||
hwc_session->HotPlug(HWC_DISPLAY_EXTERNAL, HWC2::Connection::Connected);
|
||||
status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
|
||||
}
|
||||
}
|
||||
|
||||
// If validate fails, cancel the sequence lock so that other operations
|
||||
// (such as Dump or SetPowerMode) may succeed without blocking on the condition
|
||||
if (status == HWC2::Error::BadDisplay) {
|
||||
SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
|
||||
}
|
||||
|
||||
return INT32(status);
|
||||
}
|
||||
|
||||
|
@ -825,8 +886,7 @@ int32_t HWCSession::ConnectDisplay(int disp) {
|
|||
hwc_display_[HWC_DISPLAY_PRIMARY]->GetFrameBufferResolution(&primary_width, &primary_height);
|
||||
|
||||
if (disp == HWC_DISPLAY_EXTERNAL) {
|
||||
status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_, primary_width,
|
||||
primary_height, qservice_, false, &hwc_display_[disp]);
|
||||
status = CreateExternalDisplay(disp, primary_width, primary_height);
|
||||
} else {
|
||||
DLOGE("Invalid display type");
|
||||
return -1;
|
||||
|
@ -1006,8 +1066,6 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa
|
|||
android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
|
||||
*input_parcel,
|
||||
android::Parcel *output_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int config = input_parcel->readInt32();
|
||||
int dpy = input_parcel->readInt32();
|
||||
int error = android::BAD_VALUE;
|
||||
|
@ -1017,6 +1075,7 @@ android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android:
|
|||
return android::BAD_VALUE;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
|
||||
if (hwc_display_[dpy]) {
|
||||
error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
|
||||
if (error == 0) {
|
||||
|
@ -1033,7 +1092,7 @@ android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android:
|
|||
}
|
||||
|
||||
android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
uint32_t operation = UINT32(input_parcel->readInt32());
|
||||
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
|
||||
|
@ -1059,20 +1118,19 @@ android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_
|
|||
}
|
||||
|
||||
android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
uint32_t mode = UINT32(input_parcel->readInt32());
|
||||
return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
|
||||
}
|
||||
|
||||
android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
|
||||
uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
|
||||
if (error != kErrorNone) {
|
||||
|
@ -1082,6 +1140,7 @@ android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_par
|
|||
}
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
|
||||
error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
|
||||
if (error != kErrorNone) {
|
||||
|
@ -1091,6 +1150,7 @@ android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_par
|
|||
}
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
|
||||
error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
|
||||
if (error != kErrorNone) {
|
||||
|
@ -1103,25 +1163,26 @@ android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_par
|
|||
}
|
||||
|
||||
void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
|
||||
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
|
||||
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
|
||||
hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
|
||||
hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
|
||||
}
|
||||
|
@ -1129,8 +1190,6 @@ void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
|
|||
}
|
||||
|
||||
android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DisplayError error = kErrorNone;
|
||||
uint32_t dpy = UINT32(input_parcel->readInt32());
|
||||
|
||||
|
@ -1139,6 +1198,7 @@ android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_pa
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
DLOGI("Primary display is not initialized");
|
||||
return -EINVAL;
|
||||
|
@ -1159,6 +1219,8 @@ android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_
|
|||
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
|
||||
auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
|
||||
auto device = static_cast<hwc2_device_t *>(this);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
|
||||
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
|
||||
if (err != HWC2_ERROR_NONE)
|
||||
return -EINVAL;
|
||||
|
@ -1166,7 +1228,7 @@ android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_
|
|||
}
|
||||
|
||||
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
// TODO(user): Do we really need a lock here?
|
||||
|
||||
int type = input_parcel->readInt32();
|
||||
bool enable = (input_parcel->readInt32() > 0);
|
||||
|
@ -1240,56 +1302,73 @@ android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel
|
|||
return ret;
|
||||
}
|
||||
|
||||
switch (pending_action.action) {
|
||||
case kInvalidating:
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kEnterQDCMMode:
|
||||
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kExitQDCMMode:
|
||||
ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kApplySolidFill:
|
||||
ret =
|
||||
color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kDisableSolidFill:
|
||||
ret =
|
||||
color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kSetPanelBrightness:
|
||||
brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
|
||||
if (brightness_value == NULL) {
|
||||
DLOGE("Brightness value is Null");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (HWC_DISPLAY_PRIMARY == display_id)
|
||||
ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
|
||||
break;
|
||||
case kEnableFrameCapture:
|
||||
ret = color_mgr_->SetFrameCapture(pending_action.params, true,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kDisableFrameCapture:
|
||||
ret = color_mgr_->SetFrameCapture(pending_action.params, false,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kConfigureDetailedEnhancer:
|
||||
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kNoAction:
|
||||
break;
|
||||
default:
|
||||
DLOGW("Invalid pending action = %d!", pending_action.action);
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t action = pending_action.action;
|
||||
int count = -1;
|
||||
while (action > 0) {
|
||||
count++;
|
||||
int32_t bit = (action & 1);
|
||||
action = action >> 1;
|
||||
|
||||
if (!bit)
|
||||
continue;
|
||||
|
||||
DLOGV_IF(kTagQDCM, "pending action = %d", BITMAP(count));
|
||||
switch (BITMAP(count)) {
|
||||
case kInvalidating:
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kEnterQDCMMode:
|
||||
ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kExitQDCMMode:
|
||||
ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kApplySolidFill:
|
||||
ret = color_mgr_->SetSolidFill(pending_action.params,
|
||||
true, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kDisableSolidFill:
|
||||
ret = color_mgr_->SetSolidFill(pending_action.params,
|
||||
false, hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kSetPanelBrightness:
|
||||
brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
|
||||
if (brightness_value == NULL) {
|
||||
DLOGE("Brightness value is Null");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (HWC_DISPLAY_PRIMARY == display_id)
|
||||
ret = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(*brightness_value);
|
||||
break;
|
||||
case kEnableFrameCapture:
|
||||
ret = color_mgr_->SetFrameCapture(pending_action.params, true,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kDisableFrameCapture:
|
||||
ret = color_mgr_->SetFrameCapture(pending_action.params, false,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
break;
|
||||
case kConfigureDetailedEnhancer:
|
||||
ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kModeSet:
|
||||
ret = static_cast<int>
|
||||
(hwc_display_[HWC_DISPLAY_PRIMARY]->RestoreColorTransform());
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
break;
|
||||
case kNoAction:
|
||||
break;
|
||||
default:
|
||||
DLOGW("Invalid pending action = %d!", pending_action.action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for display API getter case, marshall returned params into out_parcel.
|
||||
output_parcel->writeInt32(ret);
|
||||
HWCColorManager::MarshallStructIntoParcel(resp_payload, output_parcel);
|
||||
|
@ -1301,7 +1380,7 @@ android::status_t HWCSession::QdcmCMDHandler(const android::Parcel *input_parcel
|
|||
}
|
||||
|
||||
void HWCSession::UEventHandler(const char *uevent_data, int length) {
|
||||
if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
|
||||
if (!strcasecmp(uevent_data, HWC_UEVENT_SWITCH_HDMI)) {
|
||||
DLOGI("Uevent HDMI = %s", uevent_data);
|
||||
int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
|
||||
if (connected >= 0) {
|
||||
|
@ -1310,7 +1389,7 @@ void HWCSession::UEventHandler(const char *uevent_data, int length) {
|
|||
DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
|
||||
}
|
||||
}
|
||||
} else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
|
||||
} else if (!strcasecmp(uevent_data, HWC_UEVENT_GRAPHICS_FB0)) {
|
||||
DLOGI("Uevent FB0 = %s", uevent_data);
|
||||
int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
|
||||
if (panel_reset == 0) {
|
||||
|
@ -1364,31 +1443,34 @@ int HWCSession::HotPlugHandler(bool connected) {
|
|||
// To prevent sending events to client while a lock is held, acquire scope locks only within
|
||||
// below scope so that those get automatically unlocked after the scope ends.
|
||||
do {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
// If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
|
||||
// if it is already created, but got disconnected/connected again,
|
||||
// just toggle display status and do not notify surfaceflinger.
|
||||
// If HDMI is not primary, create/destroy external display normally.
|
||||
if (hdmi_is_primary_) {
|
||||
SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
|
||||
} else {
|
||||
status = HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
|
||||
qservice_, &hwc_display_[HWC_DISPLAY_PRIMARY]);
|
||||
status = CreateExternalDisplay(HWC_DISPLAY_PRIMARY);
|
||||
notify_hotplug = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Primary display must be connected for HDMI as secondary cases.
|
||||
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
DLOGE("Primary display is not connected.");
|
||||
return -1;
|
||||
{
|
||||
SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
// Primary display must be connected for HDMI as secondary cases.
|
||||
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
DLOGE("Primary display is not connected.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
|
||||
// Connect external display if virtual display is not connected.
|
||||
// Else, defer external display connection and process it when virtual display
|
||||
// tears down; Do not notify SurfaceFlinger since connection is deferred now.
|
||||
|
@ -1403,6 +1485,7 @@ int HWCSession::HotPlugHandler(bool connected) {
|
|||
external_pending_connect_ = true;
|
||||
}
|
||||
} else {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
|
||||
// Do not return error if external display is not in connected status.
|
||||
// Due to virtual display concurrency, external display connection might be still pending
|
||||
// but hdmi got disconnected before pending connection could be processed.
|
||||
|
@ -1437,7 +1520,7 @@ int HWCSession::HotPlugHandler(bool connected) {
|
|||
}
|
||||
|
||||
int HWCSession::GetVsyncPeriod(int disp) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SCOPE_LOCK(locker_[disp]);
|
||||
// default value
|
||||
int32_t vsync_period = 1000000000l / 60;
|
||||
auto attribute = HWC2::Attribute::VsyncPeriod;
|
||||
|
@ -1451,14 +1534,12 @@ int HWCSession::GetVsyncPeriod(int disp) {
|
|||
|
||||
android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
|
||||
android::Parcel *output_parcel) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int dpy = input_parcel->readInt32();
|
||||
|
||||
if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
|
||||
return android::BAD_VALUE;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
|
||||
if (!hwc_display_[dpy]) {
|
||||
return android::NO_INIT;
|
||||
}
|
||||
|
@ -1495,4 +1576,26 @@ void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
|
|||
}
|
||||
}
|
||||
|
||||
int HWCSession::CreateExternalDisplay(int disp, uint32_t primary_width,
|
||||
uint32_t primary_height, bool use_primary_res) {
|
||||
uint32_t panel_bpp = 0;
|
||||
uint32_t pattern_type = 0;
|
||||
if (qdutils::isDPConnected()) {
|
||||
qdutils::getDPTestConfig(&panel_bpp, &pattern_type);
|
||||
}
|
||||
if (panel_bpp && pattern_type) {
|
||||
return HWCDisplayExternalTest::Create(core_intf_, &buffer_allocator_, &callbacks_,
|
||||
qservice_, panel_bpp,
|
||||
pattern_type, &hwc_display_[disp]);
|
||||
}
|
||||
if (use_primary_res) {
|
||||
return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
|
||||
primary_width, primary_height, qservice_,
|
||||
use_primary_res, &hwc_display_[disp]);
|
||||
} else {
|
||||
return HWCDisplayExternal::Create(core_intf_, &buffer_allocator_, &callbacks_,
|
||||
qservice_, &hwc_display_[disp]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sdm
|
||||
|
|
|
@ -78,6 +78,10 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli
|
|||
static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display,
|
||||
HWC2::Error (HWCDisplay::*member)(Args...), Args... args) {
|
||||
if (!device) {
|
||||
return HWC2_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
if (display >= HWC_NUM_DISPLAY_TYPES) {
|
||||
return HWC2_ERROR_BAD_DISPLAY;
|
||||
}
|
||||
|
||||
|
@ -167,6 +171,9 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli
|
|||
int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
|
||||
int32_t GetPanelBrightness(int *level);
|
||||
int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
|
||||
int32_t CreateExternalDisplay(int disp, uint32_t primary_width = 0,
|
||||
uint32_t primary_height = 0,
|
||||
bool use_primary_res = false);
|
||||
|
||||
// service methods
|
||||
void StartServices();
|
||||
|
@ -218,7 +225,7 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli
|
|||
void Refresh(hwc2_display_t display);
|
||||
void HotPlug(hwc2_display_t display, HWC2::Connection state);
|
||||
|
||||
static Locker locker_;
|
||||
static Locker locker_[HWC_NUM_DISPLAY_TYPES];
|
||||
CoreInterface *core_intf_ = nullptr;
|
||||
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
|
||||
HWCCallbacks callbacks_;
|
||||
|
|
|
@ -92,12 +92,12 @@ HWCDisplay::DisplayStatus MapExternalStatus(IDisplayConfig::DisplayExternalStatu
|
|||
// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow.
|
||||
Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
|
||||
isDisplayConnected_cb _hidl_cb) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int32_t error = -EINVAL;
|
||||
bool connected = false;
|
||||
|
||||
int disp_id = MapDisplayType(dpy);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
|
||||
if (disp_id >= 0) {
|
||||
connected = hwc_display_[disp_id];
|
||||
error = 0;
|
||||
|
@ -109,12 +109,11 @@ Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
|
|||
}
|
||||
|
||||
int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
DLOGI("Display = %d, Status = %d", disp_id, status);
|
||||
|
||||
if (disp_id == HWC_DISPLAY_PRIMARY) {
|
||||
|
@ -135,8 +134,7 @@ Return<int32_t> HWCSession::setSecondayDisplayStatus(IDisplayConfig::DisplayType
|
|||
|
||||
Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
|
||||
uint32_t refreshRate) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
|
||||
|
||||
switch (op) {
|
||||
|
@ -158,9 +156,13 @@ Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRef
|
|||
}
|
||||
|
||||
int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (disp_id >= 0 && hwc_display_[disp_id]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
|
||||
if (hwc_display_[disp_id]) {
|
||||
return hwc_display_[disp_id]->GetDisplayConfigCount(count);
|
||||
}
|
||||
|
||||
|
@ -178,9 +180,13 @@ Return<void> HWCSession::getConfigCount(IDisplayConfig::DisplayType dpy,
|
|||
}
|
||||
|
||||
int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
|
||||
SCOPE_LOCK(locker_);
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (disp_id >= 0 && hwc_display_[disp_id]) {
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
|
||||
if (hwc_display_[disp_id]) {
|
||||
return hwc_display_[disp_id]->GetActiveDisplayConfig(config);
|
||||
}
|
||||
|
||||
|
@ -198,12 +204,11 @@ Return<void> HWCSession::getActiveConfig(IDisplayConfig::DisplayType dpy,
|
|||
}
|
||||
|
||||
int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
int32_t error = -EINVAL;
|
||||
if (hwc_display_[disp_id]) {
|
||||
error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
|
||||
|
@ -222,12 +227,11 @@ Return<int32_t> HWCSession::setActiveConfig(IDisplayConfig::DisplayType dpy, uin
|
|||
Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
|
||||
IDisplayConfig::DisplayType dpy,
|
||||
getDisplayAttributes_cb _hidl_cb) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int32_t error = -EINVAL;
|
||||
IDisplayConfig::DisplayAttributes display_attributes = {};
|
||||
|
||||
int disp_id = MapDisplayType(dpy);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
if (disp_id >= 0 && hwc_display_[disp_id]) {
|
||||
DisplayConfigVariableInfo hwc_display_attributes;
|
||||
error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(static_cast<int>(configIndex),
|
||||
|
@ -247,9 +251,9 @@ Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
|
|||
}
|
||||
|
||||
Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
int32_t error = -EINVAL;
|
||||
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(static_cast<int>(level));
|
||||
if (error) {
|
||||
|
@ -261,8 +265,7 @@ Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
|
|||
}
|
||||
|
||||
int32_t HWCSession::GetPanelBrightness(int *level) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
int32_t error = -EINVAL;
|
||||
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
|
@ -285,14 +288,13 @@ Return<void> HWCSession::getPanelBrightness(getPanelBrightness_cb _hidl_cb) {
|
|||
}
|
||||
|
||||
int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
DLOGI("Display %d", disp_id);
|
||||
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
if (disp_id != HWC_DISPLAY_EXTERNAL) {
|
||||
DLOGE("Not supported for display");
|
||||
} else if (!hwc_display_[disp_id]) {
|
||||
|
@ -310,16 +312,13 @@ Return<int32_t> HWCSession::minHdcpEncryptionLevelChanged(IDisplayConfig::Displa
|
|||
}
|
||||
|
||||
Return<int32_t> HWCSession::refreshScreen() {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
if (disp_id < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -329,6 +328,7 @@ int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
|
||||
if (!hwc_display) {
|
||||
DLOGE("primary display object is not instantiated");
|
||||
|
@ -352,7 +352,7 @@ int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
|
|||
Refresh(HWC_DISPLAY_PRIMARY);
|
||||
|
||||
// Wait until partial update control is complete
|
||||
int32_t error = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
|
||||
int32_t error = locker_[disp_id].WaitFinite(kPartialUpdateControlTimeoutMs);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ Return<int32_t> HWCSession::controlPartialUpdate(IDisplayConfig::DisplayType dpy
|
|||
}
|
||||
|
||||
Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
int32_t error = -EINVAL;
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
|
@ -376,7 +376,7 @@ Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
|
|||
}
|
||||
|
||||
Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value);
|
||||
|
@ -388,8 +388,6 @@ Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
|
|||
|
||||
Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
|
||||
getHDRCapabilities_cb _hidl_cb) {
|
||||
SCOPE_LOCK(locker_);
|
||||
|
||||
int32_t error = -EINVAL;
|
||||
IDisplayConfig::DisplayHDRCapabilities hdr_caps = {};
|
||||
|
||||
|
@ -400,6 +398,7 @@ Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
|
|||
break;
|
||||
}
|
||||
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
|
||||
HWCDisplay *hwc_display = hwc_display_[disp_id];
|
||||
if (!hwc_display) {
|
||||
DLOGE("Display = %d is not connected.", disp_id);
|
||||
|
@ -438,7 +437,7 @@ Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
|
|||
}
|
||||
|
||||
Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
|
||||
|
||||
|
@ -457,7 +456,7 @@ Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
|
|||
}
|
||||
|
||||
int32_t HWCSession::DisplayBWTransactionPending(bool *status) {
|
||||
SCOPE_LOCK(locker_);
|
||||
SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
|
||||
|
||||
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
|
||||
if (sync_wait(bw_mode_release_fd_, 0) < 0) {
|
||||
|
|
Loading…
Reference in New Issue