Merge "sdm: Avoid reading HWCapabilities multiple times."
diff --git a/gpu_tonemapper/EGLImageWrapper.cpp b/gpu_tonemapper/EGLImageWrapper.cpp
index eb0a2ca..298475f 100644
--- a/gpu_tonemapper/EGLImageWrapper.cpp
+++ b/gpu_tonemapper/EGLImageWrapper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -22,8 +22,6 @@
#include <gralloc_priv.h>
#include <ui/GraphicBuffer.h>
-std::map<int, EGLImageBuffer *> EGLImageWrapper::eglImageBufferMap;
-
//-----------------------------------------------------------------------------
EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
//-----------------------------------------------------------------------------
@@ -65,4 +63,4 @@
delete it->second;
}
eglImageBufferMap.clear();
-}
\ No newline at end of file
+}
diff --git a/gpu_tonemapper/EGLImageWrapper.h b/gpu_tonemapper/EGLImageWrapper.h
index d7fc84b..90aaf58 100644
--- a/gpu_tonemapper/EGLImageWrapper.h
+++ b/gpu_tonemapper/EGLImageWrapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -24,11 +24,11 @@
#include "EGLImageBuffer.h"
class EGLImageWrapper {
- static std::map<int, EGLImageBuffer *> eglImageBufferMap;
+ std::map<int, EGLImageBuffer *> eglImageBufferMap;
public:
- static EGLImageBuffer *wrap(const void *pvt_handle);
- static void destroy();
+ EGLImageBuffer *wrap(const void *pvt_handle);
+ void destroy();
};
-#endif //__TONEMAPPER_EGLIMAGEWRAPPER_H__
\ No newline at end of file
+#endif //__TONEMAPPER_EGLIMAGEWRAPPER_H__
diff --git a/gpu_tonemapper/TonemapFactory.cpp b/gpu_tonemapper/TonemapFactory.cpp
index 81e9f7f..cffc33a 100644
--- a/gpu_tonemapper/TonemapFactory.cpp
+++ b/gpu_tonemapper/TonemapFactory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -19,7 +19,6 @@
#include "TonemapFactory.h"
#include <utils/Log.h>
-#include "EGLImageWrapper.h"
#include "Tonemapper.h"
#include "engine.h"
@@ -41,8 +40,6 @@
void TonemapperFactory_Destroy()
//------------------------------------------
{
- // clear EGLImage mappings
- EGLImageWrapper::destroy();
// shutdown the engine
engine_shutdown();
}
diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp
index 957c133..5f2f974 100644
--- a/gpu_tonemapper/Tonemapper.cpp
+++ b/gpu_tonemapper/Tonemapper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -32,6 +32,7 @@
tonemapTexture = 0;
lutXformTexture = 0;
programID = 0;
+ eglImageWrapper = new EGLImageWrapper();
}
//-----------------------------------------------------------------------------
@@ -41,6 +42,13 @@
engine_deleteInputBuffer(tonemapTexture);
engine_deleteInputBuffer(lutXformTexture);
engine_deleteProgram(programID);
+
+ // clear EGLImage mappings
+ if (eglImageWrapper != 0) {
+ eglImageWrapper->destroy();
+ delete eglImageWrapper;
+ eglImageWrapper = 0;
+ }
}
//-----------------------------------------------------------------------------
@@ -95,8 +103,8 @@
engine_bind();
// create eglimages if required
- EGLImageBuffer *dst_buffer = EGLImageWrapper::wrap(dst);
- EGLImageBuffer *src_buffer = EGLImageWrapper::wrap(src);
+ EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
+ EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src);
// bind the program
engine_setProgram(programID);
diff --git a/gpu_tonemapper/Tonemapper.h b/gpu_tonemapper/Tonemapper.h
index 9c41670..0f9bd51 100644
--- a/gpu_tonemapper/Tonemapper.h
+++ b/gpu_tonemapper/Tonemapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -23,11 +23,14 @@
#define TONEMAP_FORWARD 0
#define TONEMAP_INVERSE 1
+#include "EGLImageWrapper.h"
+
class Tonemapper {
private:
unsigned int tonemapTexture;
unsigned int lutXformTexture;
unsigned int programID;
+ EGLImageWrapper* eglImageWrapper;
Tonemapper();
public:
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index c3aa86e..877b54e 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -93,19 +93,31 @@
continue;
}
+ if (size == 0)
+ return -EINVAL;
+
+ if (unaccounted_size + size < size)
+ return -ERANGE;
+
if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
if (flags[6] == 'Y') {
- accounted_size += mapsize;
- unaccounted_size += size - mapsize;
- } else
- unaccounted_size += size;
+ if (accounted_size + mapsize < accounted_size)
+ return -ERANGE;
+ accounted_size += mapsize;
+
+ if (mapsize > size)
+ return -EINVAL;
+
+ unaccounted_size += size - mapsize;
+ } else
+ unaccounted_size += size;
} else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
if (strcmp(line_usage, "egl_surface") == 0)
unaccounted_size += size;
else if (egl_surface_count == 0)
- unaccounted_size += size / (egl_image_count ? egl_image_count : 1);
+ unaccounted_size += size / (egl_image_count ? egl_image_count : 1);
}
}
diff --git a/sdm/include/utils/utils.h b/sdm/include/utils/utils.h
index 5f621dd..ed2c6ae 100644
--- a/sdm/include/utils/utils.h
+++ b/sdm/include/utils/utils.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 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
@@ -34,6 +34,7 @@
float gcd(float a, float b);
float lcm(float a, float b);
+void CloseFd(int *fd);
} // namespace sdm
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 111e386..b5233ae 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -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
@@ -1041,7 +1041,7 @@
bool HWDevice::EnableHotPlugDetection(int enable) {
char hpdpath[kMaxStringLength];
- char value = enable ? '1' : '0';
+ const char *value = enable ? "1" : "0";
// Enable HPD for all pluggable devices.
for (int i = 0; i < kFBNodeMax; i++) {
@@ -1050,7 +1050,7 @@
if (panel_info.is_pluggable == true) {
snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, i);
- ssize_t length = SysFsWrite(hpdpath, &value, sizeof(value));
+ ssize_t length = SysFsWrite(hpdpath, value, 1);
if (length <= 0) {
return false;
}
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 6d8cb15..e1ce108 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -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
@@ -157,7 +157,6 @@
}
tone_mapper_ = new HWCToneMapper();
- tone_mapper_->Init();
display_intf_->GetRefreshRateRange(&min_refresh_rate_, &max_refresh_rate_);
current_refresh_rate_ = max_refresh_rate_;
diff --git a/sdm/libs/hwc/hwc_tonemapper.cpp b/sdm/libs/hwc/hwc_tonemapper.cpp
index 18a38fe..93ff452 100644
--- a/sdm/libs/hwc/hwc_tonemapper.cpp
+++ b/sdm/libs/hwc/hwc_tonemapper.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 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
@@ -41,6 +41,7 @@
#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/rect.h>
+#include <utils/utils.h>
#include <vector>
@@ -51,159 +52,26 @@
namespace sdm {
-int HWCToneMapper::Init() {
- for (uint32_t i = 0; i < kNumIntermediateBuffers; i++) {
- intermediate_buffer_[i] = NULL;
- release_fence_fd_[i] = -1;
- }
- return 0;
+ToneMapSession::~ToneMapSession() {
+ delete gpu_tone_mapper_;
+ gpu_tone_mapper_ = NULL;
+ FreeIntermediateBuffers();
}
-void HWCToneMapper::DeInit() {
- return;
-}
-
-int HWCToneMapper::HandleToneMap(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
- uint32_t layer_count = UINT32(layer_stack->layers.size());
- std::vector<uint32_t> tonemap_layer_index = {};
- Layer *layer = NULL;
- uint32_t i = 0;
- uint32_t gpu_count = 0;
- int fence_fd = -1;
- int acquire_fd = -1;
- int merged_fd = -1;
- hwc_layer_1_t *hwc_layer = NULL;
- const private_handle_t *dst_hnd = NULL;
- const private_handle_t *src_hnd = NULL;
- bool yuv_tonemap_request = false;
-
- for (; i < layer_count; i++) {
- layer = layer_stack->layers.at(i);
- if (layer->request.flags.tone_map) {
- tonemap_layer_index.push_back(i);
- if (layer->input_buffer.flags.video) {
- yuv_tonemap_request = true;
- }
- break;
- }
- if (layer->composition == kCompositionGPU) {
- gpu_count++;
- }
- }
-
- if (tonemap_layer_index.empty()) {
- return 0;
- }
- // gpu count can be 0 when a layer is on FB and in next cycle it doesn't update and SDM marks
- // it as SDE comp
- if (gpu_count == 0 && !yuv_tonemap_request) {
- // TODO(akumarkr): Remove goto when added multiple instance support
- // intermediate buffer can be null
- goto update_fd;
- }
-
- if (intermediate_buffer_[0] == NULL) {
- DLOGI("format = %d width = %d height = %d", layer->request.format, layer->request.width,
- layer->request.height);
- int usage = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE);
- int error = 0;
- if (layer->request.flags.secure) {
- usage = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP);
- usage |= INT(GRALLOC_USAGE_PROTECTED);
- }
- int format;
- error = buffer_allocator_.SetBufferInfo(layer->request.format, &format, &usage);
-
- AllocateIntermediateBuffers(layer->request.width, layer->request.height, format, usage);
- }
- current_intermediate_buffer_index_ =
- (current_intermediate_buffer_index_ + 1) % kNumIntermediateBuffers;
-
- if (!gpu_tone_mapper_) {
- Color10Bit *grid_entries = NULL;
- int grid_size = 0;
- if (layer->lut_3d.validGridEntries) {
- grid_entries = layer->lut_3d.gridEntries;
- grid_size = INT(layer->lut_3d.gridSize);
- }
- // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
- // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
- // for Tonemapping.
- if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) {
- // Atleast lutEntries must be valid for GPU Tonemapper.
- DLOGE("Invalid Lut Entries or lut dimention = %d", layer->lut_3d.dim);
- return -1;
- }
- // HDR -> SDR = FORWARD and SDR - > HDR is INVERSE
- int tonemap_type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
- gpu_tone_mapper_ = TonemapperFactory_GetInstance(tonemap_type, layer->lut_3d.lutEntries,
- layer->lut_3d.dim, grid_entries, grid_size);
- if (gpu_tone_mapper_ == NULL) {
- DLOGE("Get Tonemapper failed");
- return -1;
- }
- }
-
- hwc_layer = &content_list->hwLayers[i];
- dst_hnd = intermediate_buffer_[current_intermediate_buffer_index_];
- src_hnd = static_cast<const private_handle_t *>(hwc_layer->handle);
- acquire_fd = dup(layer->input_buffer.acquire_fence_fd);
- buffer_sync_handler_.SyncMerge(release_fence_fd_[current_intermediate_buffer_index_],
- acquire_fd, &merged_fd);
-
- if (acquire_fd >= 0) {
- CloseFd(&acquire_fd);
- }
-
- if (release_fence_fd_[current_intermediate_buffer_index_] >= 0) {
- CloseFd(&release_fence_fd_[current_intermediate_buffer_index_]);
- }
- DTRACE_BEGIN("GPU_TM_BLIT");
- fence_fd = gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd),
- reinterpret_cast<const void *>(src_hnd), merged_fd);
- DTRACE_END();
-
-
- DumpToneMapOutput(&fence_fd);
-
-update_fd:
- // Acquire fence will be closed by HWC Display
- // Fence returned by GPU will be closed in PostCommit
- layer->input_buffer.acquire_fence_fd = fence_fd;
- layer->input_buffer.size = intermediate_buffer_[current_intermediate_buffer_index_]->size;
- layer->input_buffer.planes[0].fd = intermediate_buffer_[current_intermediate_buffer_index_]->fd;
-
- active_ = true;
-
- tonemap_layer_index.clear();
-
- return 0;
-}
-
-int HWCToneMapper::AllocateIntermediateBuffers(uint32_t width, uint32_t height, int32_t format,
- int32_t usage) {
- int status = 0;
- if (width <= 0 || height <= 0) {
- return false;
- }
-
- for (uint32_t i = 0; i < kNumIntermediateBuffers; i++) {
- status = alloc_buffer(&intermediate_buffer_[i], INT(width), INT(height), INT(format),
- INT(usage));
+DisplayError ToneMapSession::AllocateIntermediateBuffers(int w, int h, int format, int usage) {
+ for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
+ int status = alloc_buffer(&intermediate_buffer_[i], w, h, format, usage);
if (status < 0) {
- DLOGE("Allocation of Intermediate Buffer failed");
FreeIntermediateBuffers();
- break;
+ return kErrorMemory;
}
}
- return status;
+ return kErrorNone;
}
-void HWCToneMapper::FreeIntermediateBuffers() {
- if (!intermediate_buffer_[0]) {
- return;
- }
- for (uint32_t i = 0; i < kNumIntermediateBuffers; i++) {
+
+void ToneMapSession::FreeIntermediateBuffers() {
+ for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
private_handle_t *buffer = intermediate_buffer_[i];
if (buffer) {
// Free the valid fence
@@ -216,60 +84,148 @@
}
}
-void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
- uint32_t layer_count = UINT32(layer_stack->layers.size());
- std::vector<uint32_t> tonemap_layer_index = {};
- Layer *layer = NULL;
- int rel_fence_fd = -1;
- bool has_tonemap = false;
- uint32_t i;
+void ToneMapSession::UpdateBuffer(int acquire_fence, LayerBuffer *buffer) {
+ // Acquire fence will be closed by HWC Display.
+ // Fence returned by GPU will be closed in PostCommit.
+ buffer->acquire_fence_fd = acquire_fence;
+ buffer->size = intermediate_buffer_[current_buffer_index_]->size;
+ buffer->planes[0].fd = intermediate_buffer_[current_buffer_index_]->fd;
+}
- for (i = 0; i < layer_count; i++) {
- layer = layer_stack->layers.at(i);
+void ToneMapSession::SetReleaseFence(int fd) {
+ CloseFd(&release_fence_fd_[current_buffer_index_]);
+ // Used to give to GPU tonemapper along with input layer fd
+ release_fence_fd_[current_buffer_index_] = dup(fd);
+}
+
+void ToneMapSession::SetToneMapConfig(Layer *layer) {
+ // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE
+ tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
+ tone_map_config_.colorPrimaries = layer->input_buffer.color_metadata.colorPrimaries;
+ tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer;
+ tone_map_config_.secure = layer->request.flags.secure;
+ tone_map_config_.format = layer->request.format;
+}
+
+bool ToneMapSession::IsSameToneMapConfig(Layer *layer) {
+ LayerBuffer& buffer = layer->input_buffer;
+ private_handle_t *handle = intermediate_buffer_[0];
+ int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
+
+ return ((tonemap_type == tone_map_config_.type) &&
+ (buffer.color_metadata.colorPrimaries == tone_map_config_.colorPrimaries) &&
+ (buffer.color_metadata.transfer == tone_map_config_.transfer) &&
+ (layer->request.flags.secure == tone_map_config_.secure) &&
+ (layer->request.format == tone_map_config_.format) &&
+ (layer->request.width == UINT32(handle->unaligned_width)) &&
+ (layer->request.height == UINT32(handle->unaligned_height)));
+}
+
+int HWCToneMapper::HandleToneMap(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
+ uint32_t gpu_count = 0;
+ DisplayError error = kErrorNone;
+
+ for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
+ uint32_t session_index = 0;
+ Layer *layer = layer_stack->layers.at(i);
+ if (layer->composition == kCompositionGPU) {
+ gpu_count++;
+ }
+
if (layer->request.flags.tone_map) {
- tonemap_layer_index.push_back(i);
- has_tonemap = true;
- break;
+ switch (layer->composition) {
+ case kCompositionGPUTarget:
+ if (!gpu_count) {
+ // When all layers are on FrameBuffer and if they do not update in the next draw cycle,
+ // then SDM marks them for SDE Composition because the cached FB layer gets displayed.
+ // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
+ // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
+ ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_);
+ fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
+ fb_tone_map_session->layer_index_ = INT(i);
+ fb_tone_map_session->acquired_ = true;
+ return 0;
+ }
+ error = AcquireToneMapSession(layer, &session_index);
+ fb_session_index_ = session_index;
+ break;
+ default:
+ error = AcquireToneMapSession(layer, &session_index);
+ break;
+ }
+
+ if (error != kErrorNone) {
+ Terminate();
+ return -1;
+ }
+
+ ToneMapSession *session = tone_map_sessions_.at(session_index);
+ ToneMap(&content_list->hwLayers[i], layer, session);
+ session->layer_index_ = INT(i);
}
}
- if (has_tonemap) {
- LayerBuffer &layer_buffer = layer->input_buffer;
+ return 0;
+}
- rel_fence_fd = layer_buffer.release_fence_fd;
- // close the fd returned by GPU Tonemapper
- CloseFd(&layer_buffer.acquire_fence_fd);
+void HWCToneMapper::ToneMap(hwc_layer_1_t *hwc_layer, Layer* layer, ToneMapSession *session) {
+ int fence_fd = -1;
+ int acquire_fd = -1;
+ int merged_fd = -1;
- SetReleaseFence(rel_fence_fd);
+ uint8_t buffer_index = session->current_buffer_index_;
+ const private_handle_t *dst_hnd = session->intermediate_buffer_[buffer_index];
+ const private_handle_t *src_hnd = static_cast<const private_handle_t *>(hwc_layer->handle);
+
+ acquire_fd = dup(layer->input_buffer.acquire_fence_fd);
+ buffer_sync_handler_.SyncMerge(session->release_fence_fd_[buffer_index], acquire_fd, &merged_fd);
+
+ if (acquire_fd >= 0) {
+ CloseFd(&acquire_fd);
}
- active_ = false;
+ if (session->release_fence_fd_[buffer_index] >= 0) {
+ CloseFd(&session->release_fence_fd_[buffer_index]);
+ }
+
+ DTRACE_BEGIN("GPU_TM_BLIT");
+ fence_fd = session->gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd),
+ reinterpret_cast<const void *>(src_hnd), merged_fd);
+ DTRACE_END();
+
+ DumpToneMapOutput(session, &fence_fd);
+ session->UpdateBuffer(fence_fd, &layer->input_buffer);
}
-void HWCToneMapper::SetReleaseFence(int fd) {
- CloseFd(&release_fence_fd_[current_intermediate_buffer_index_]);
- // used to give to GPU tonemapper along with input layer fd
- release_fence_fd_[current_intermediate_buffer_index_] = dup(fd);
-}
-
-void HWCToneMapper::CloseFd(int *fd) {
- if (*fd >= 0) {
- close(*fd);
- *fd = -1;
+void HWCToneMapper::PostCommit(LayerStack *layer_stack) {
+ auto it = tone_map_sessions_.begin();
+ while (it != tone_map_sessions_.end()) {
+ uint32_t session_index = UINT32(std::distance(tone_map_sessions_.begin(), it));
+ ToneMapSession *session = tone_map_sessions_.at(session_index);
+ Layer *layer = layer_stack->layers.at(UINT32(session->layer_index_));
+ if (session->acquired_) {
+ // Close the fd returned by GPU ToneMapper and set release fence.
+ LayerBuffer &layer_buffer = layer->input_buffer;
+ CloseFd(&layer_buffer.acquire_fence_fd);
+ session->SetReleaseFence(layer_buffer.release_fence_fd);
+ session->acquired_ = false;
+ it++;
+ } else {
+ delete session;
+ it = tone_map_sessions_.erase(it);
+ }
}
}
void HWCToneMapper::Terminate() {
- if (!gpu_tone_mapper_) {
- return;
+ if (tone_map_sessions_.size()) {
+ while (!tone_map_sessions_.empty()) {
+ delete tone_map_sessions_.back();
+ tone_map_sessions_.pop_back();
+ }
+ TonemapperFactory_Destroy();
+ fb_session_index_ = 0;
}
- // fix this on multiple instance: only delete obj and call ToneMapperDestroy on deInit.
- delete gpu_tone_mapper_;
- gpu_tone_mapper_ = NULL;
-
- TonemapperFactory_Destroy();
- FreeIntermediateBuffers();
- active_ = false;
}
void HWCToneMapper::SetFrameDumpConfig(uint32_t count) {
@@ -278,12 +234,12 @@
dump_frame_index_ = 0;
}
-void HWCToneMapper::DumpToneMapOutput(int *acquire_fd) {
+void HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
if (!dump_frame_count_) {
return;
}
- private_handle_t *target_buffer = intermediate_buffer_[current_intermediate_buffer_index_];
+ private_handle_t *target_buffer = session->intermediate_buffer_[session->current_buffer_index_];
if (*acquire_fd >= 0) {
int error = sync_wait(*acquire_fd, 1000);
@@ -293,10 +249,12 @@
}
}
- char dump_file_name[PATH_MAX];
size_t result = 0;
+ char dump_file_name[PATH_MAX];
snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
- "/tonemap_%d.raw", (dump_frame_index_));
+ "/tonemap_%dx%d_frame%d.raw", target_buffer->width, target_buffer->height,
+ dump_frame_index_);
+
FILE* fp = fopen(dump_file_name, "w+");
if (fp) {
DLOGI("base addr = %x", target_buffer->base);
@@ -308,4 +266,74 @@
CloseFd(acquire_fd);
}
+DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) {
+ Color10Bit *grid_entries = NULL;
+ int grid_size = 0;
+
+ if (layer->lut_3d.validGridEntries) {
+ grid_entries = layer->lut_3d.gridEntries;
+ grid_size = INT(layer->lut_3d.gridSize);
+ }
+
+ // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
+ // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
+ // for Tonemapping.
+ if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) {
+ // Atleast lutEntries must be valid for GPU Tonemapper.
+ DLOGE("Invalid Lut Entries or lut dimension = %d", layer->lut_3d.dim);
+ return kErrorParameters;
+ }
+
+ // Check if we can re-use an existing tone map session.
+ for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) {
+ ToneMapSession *tonemap_session = tone_map_sessions_.at(i);
+ if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer)) {
+ tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) %
+ ToneMapSession::kNumIntermediateBuffers;
+ tonemap_session->acquired_ = true;
+ *session_index = i;
+ return kErrorNone;
+ }
+ }
+
+ ToneMapSession *session = new ToneMapSession();
+
+ session->SetToneMapConfig(layer);
+ session->gpu_tone_mapper_ = TonemapperFactory_GetInstance(session->tone_map_config_.type,
+ layer->lut_3d.lutEntries,
+ layer->lut_3d.dim,
+ grid_entries, grid_size);
+
+ if (session->gpu_tone_mapper_ == NULL) {
+ DLOGE("Get Tonemapper failed!");
+ delete session;
+ return kErrorNotSupported;
+ }
+
+ int status, format;
+ DisplayError error = kErrorNone;
+ int usage = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE);
+
+ if (layer->request.flags.secure) {
+ usage = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP);
+ usage |= INT(GRALLOC_USAGE_PROTECTED);
+ }
+
+ status = buffer_allocator_.SetBufferInfo(layer->request.format, &format, &usage);
+ error = session->AllocateIntermediateBuffers(INT(layer->request.width),
+ INT(layer->request.height), format, usage);
+
+ if (error != kErrorNone) {
+ DLOGE("Allocation of Intermediate Buffers failed!");
+ delete session;
+ return error;
+ }
+
+ session->acquired_ = true;
+ tone_map_sessions_.push_back(session);
+ *session_index = UINT32(tone_map_sessions_.size() - 1);
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc/hwc_tonemapper.h b/sdm/libs/hwc/hwc_tonemapper.h
index 55105d9..0a463fe 100644
--- a/sdm/libs/hwc/hwc_tonemapper.h
+++ b/sdm/libs/hwc/hwc_tonemapper.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 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
@@ -37,7 +37,7 @@
#include <core/layer_stack.h>
#include <utils/sys.h>
-
+#include <vector>
#include "hwc_buffer_sync_handler.h"
#include "hwc_buffer_allocator.h"
@@ -45,38 +45,56 @@
namespace sdm {
+struct ToneMapConfig {
+ int type = 0;
+ ColorPrimaries colorPrimaries = ColorPrimaries_Max;
+ GammaTransfer transfer = Transfer_Max;
+ LayerBufferFormat format = kFormatRGBA8888;
+ bool secure = false;
+};
+
+class ToneMapSession {
+ public:
+ ~ToneMapSession();
+ DisplayError AllocateIntermediateBuffers(int width, int height, int format, int usage);
+ void FreeIntermediateBuffers();
+ void UpdateBuffer(int acquire_fence, LayerBuffer *buffer);
+ void SetReleaseFence(int fd);
+ void SetToneMapConfig(Layer *layer);
+ bool IsSameToneMapConfig(Layer *layer);
+
+ static const uint8_t kNumIntermediateBuffers = 2;
+ Tonemapper *gpu_tone_mapper_ = NULL;
+ ToneMapConfig tone_map_config_ = {};
+ uint8_t current_buffer_index_ = 0;
+ private_handle_t *intermediate_buffer_[kNumIntermediateBuffers] = {NULL, NULL};
+ int release_fence_fd_[kNumIntermediateBuffers] = {-1, -1};
+ bool acquired_ = false;
+ int layer_index_ = -1;
+};
+
class HWCToneMapper {
public:
HWCToneMapper() {}
~HWCToneMapper() {}
- int Init();
- void DeInit();
int HandleToneMap(hwc_display_contents_1_t *content_list, LayerStack *layer_stack);
- void Terminate();
+ bool IsActive() { return !tone_map_sessions_.empty(); }
void PostCommit(LayerStack *layer_stack);
- bool IsActive() { return active_; }
void SetFrameDumpConfig(uint32_t count);
+ void Terminate();
private:
- int AllocateIntermediateBuffers(uint32_t width, uint32_t height, int32_t format, int32_t usage);
- void FreeIntermediateBuffers();
- void SetReleaseFence(int fence_fd);
- void CloseFd(int *fd);
- void DumpToneMapOutput(int *acquire_fence);
+ void ToneMap(hwc_layer_1_t *hwc_layer, Layer *layer, ToneMapSession *session);
+ DisplayError AcquireToneMapSession(Layer *layer, uint32_t *session_index);
+ void DumpToneMapOutput(ToneMapSession *session, int *acquire_fence);
- static const uint32_t kNumIntermediateBuffers = 2;
- bool active_ = false;
-
- private_handle_t *intermediate_buffer_[kNumIntermediateBuffers] = {NULL, NULL};
- uint32_t current_intermediate_buffer_index_ = 0;
- int release_fence_fd_[kNumIntermediateBuffers];
-
+ std::vector<ToneMapSession*> tone_map_sessions_;
HWCBufferSyncHandler buffer_sync_handler_ = {};
HWCBufferAllocator buffer_allocator_ = {};
- Tonemapper *gpu_tone_mapper_ = NULL;
uint32_t dump_frame_count_ = 0;
uint32_t dump_frame_index_ = 0;
+ uint32_t fb_session_index_ = 0;
};
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f603f18..08b1aaa 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -363,13 +363,6 @@
}
}
- if (layer->color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
- (layer->color_metadata.transfer == Transfer_SMPTE_ST2084 ||
- layer->color_metadata.transfer == Transfer_HLG)) {
- layer->flags.hdr = true;
- layer_stack_.flags.hdr_present = true;
- }
-
if (layer->flags.skip) {
layer_stack_.flags.skip_present = true;
}
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 43ae0cc..befc96c 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
@@ -30,6 +30,7 @@
#include "hwc_display_external.h"
#include "hwc_display_virtual.h"
#include "hwc_color_manager.h"
+#include "hwc_socket_handler.h"
namespace sdm {
diff --git a/sdm/libs/utils/utils.cpp b/sdm/libs/utils/utils.cpp
index 5d5ee19..2ca9039 100644
--- a/sdm/libs/utils/utils.cpp
+++ b/sdm/libs/utils/utils.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 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
@@ -27,6 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <utils/sys.h>
#include <math.h>
#include <algorithm>
@@ -52,4 +53,11 @@
return (a * b) / gcd(a, b);
}
+void CloseFd(int *fd) {
+ if (*fd >= 0) {
+ Sys::close_(*fd);
+ *fd = -1;
+ }
+}
+
} // namespace sdm