1d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema/* 2d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* Copyright (c) 2016 - 2018, The Linux Foundation. All rights reserved. 3d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* 4d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* Redistribution and use in source and binary forms, with or without 5d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* modification, are permitted provided that the following conditions are 6d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* met: 7d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* * Redistributions of source code must retain the above copyright 8d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* notice, this list of conditions and the following disclaimer. 9d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* * Redistributions in binary form must reproduce the above 10d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* copyright notice, this list of conditions and the following 11d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* disclaimer in the documentation and/or other materials provided 12d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* with the distribution. 13d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* * Neither the name of The Linux Foundation nor the names of its 14d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* contributors may be used to endorse or promote products derived 15d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* from this software without specific prior written permission. 16d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* 17d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema*/ 29d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 30d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <gralloc_priv.h> 31d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <sync/sync.h> 32d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 33d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <TonemapFactory.h> 34d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 35d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <core/buffer_allocator.h> 36d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 37d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/constants.h> 38d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/debug.h> 39d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/formats.h> 40d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/rect.h> 41d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/utils.h> 42d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 43d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <vector> 44d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 45d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_debugger.h" 46d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_tonemapper.h" 47d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 48d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#define __CLASS__ "HWCToneMapper" 49d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 50d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemanamespace sdm { 51d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 52d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator) 53d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema : tone_map_task_(*this), buffer_allocator_(buffer_allocator) { 54d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info_.resize(kNumIntermediateBuffers); 55d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 56d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 57d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaToneMapSession::~ToneMapSession() { 58d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr); 59d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FreeIntermediateBuffers(); 60d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info_.clear(); 61d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 62d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 63d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::OnTask(const ToneMapTaskCode &task_code, 64d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema SyncTask<ToneMapTaskCode>::TaskContext *task_context) { 65d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema switch (task_code) { 66d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema case ToneMapTaskCode::kCodeGetInstance: { 67d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context); 68d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Lut3d &lut_3d = ctx->layer->lut_3d; 69d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Color10Bit *grid_entries = NULL; 70d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int grid_size = 0; 71d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (lut_3d.validGridEntries) { 72d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_entries = lut_3d.gridEntries; 73d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_size = INT(lut_3d.gridSize); 74d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 75d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type, 76d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema lut_3d.lutEntries, lut_3d.dim, 77d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_entries, grid_size, 78d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.secure); 79d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 80d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 81d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 82d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema case ToneMapTaskCode::kCodeBlit: { 83d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context); 84d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint8_t buffer_index = current_buffer_index_; 85d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema const void *dst_hnd = reinterpret_cast<const void *> 86d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (buffer_info_[buffer_index].private_data); 87d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema const void *src_hnd = reinterpret_cast<const void *> 88d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (ctx->layer->input_buffer.buffer_id); 89d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd); 90d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 91d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 92d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 93d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema case ToneMapTaskCode::kCodeDestroy: { 94d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete gpu_tone_mapper_; 95d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 96d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 97d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 98d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema default: 99d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 100d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 101d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 102d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 103d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaDisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) { 104d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = kErrorNone; 105d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) { 106d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema BufferInfo &buffer_info = buffer_info_[i]; 107d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info.buffer_config.width = layer->request.width; 108d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info.buffer_config.height = layer->request.height; 109d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info.buffer_config.format = layer->request.format; 110d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info.buffer_config.secure = layer->request.flags.secure; 111d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_info.buffer_config.gfx_client = true; 112d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = buffer_allocator_->AllocateBuffer(&buffer_info); 113d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 114d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FreeIntermediateBuffers(); 115d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return error; 116d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 117d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 118d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 119d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 120d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 121d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 122d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::FreeIntermediateBuffers() { 123d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) { 124d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Free the valid fence 125d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (release_fence_fd_[i] >= 0) { 126d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&release_fence_fd_[i]); 127d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 128d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema BufferInfo &buffer_info = buffer_info_[i]; 129d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (buffer_info.private_data) { 130d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_allocator_->FreeBuffer(&buffer_info); 131d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 132d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 133d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 134d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 135d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::UpdateBuffer(int acquire_fence, LayerBuffer *buffer) { 136d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Acquire fence will be closed by HWC Display. 137d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Fence returned by GPU will be closed in PostCommit. 138d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->acquire_fence_fd = acquire_fence; 139d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->size = buffer_info_[current_buffer_index_].alloc_buffer_info.size; 140d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->planes[0].fd = buffer_info_[current_buffer_index_].alloc_buffer_info.fd; 141d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 142d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 143d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::SetReleaseFence(int fd) { 144d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&release_fence_fd_[current_buffer_index_]); 145d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Used to give to GPU tonemapper along with input layer fd 146d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema release_fence_fd_[current_buffer_index_] = dup(fd); 147d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 148d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 149d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::SetToneMapConfig(Layer *layer) { 150d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE 151d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; 152d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.colorPrimaries = layer->input_buffer.color_metadata.colorPrimaries; 153d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer; 154d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.secure = layer->request.flags.secure; 155d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.format = layer->request.format; 156d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 157d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 158d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemabool ToneMapSession::IsSameToneMapConfig(Layer *layer) { 159d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema LayerBuffer& buffer = layer->input_buffer; 160d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema private_handle_t *handle = static_cast<private_handle_t *>(buffer_info_[0].private_data); 161d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; 162d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 163d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return ((tonemap_type == tone_map_config_.type) && 164d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (buffer.color_metadata.colorPrimaries == tone_map_config_.colorPrimaries) && 165d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (buffer.color_metadata.transfer == tone_map_config_.transfer) && 166d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.flags.secure == tone_map_config_.secure) && 167d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.format == tone_map_config_.format) && 168d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.width == UINT32(handle->unaligned_width)) && 169d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.height == UINT32(handle->unaligned_height))); 170d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 171d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 172d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCToneMapper::HandleToneMap(LayerStack *layer_stack) { 173d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t gpu_count = 0; 174d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = kErrorNone; 175d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 176d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint32_t i = 0; i < layer_stack->layers.size(); i++) { 177d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t session_index = 0; 178d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Layer *layer = layer_stack->layers.at(i); 179d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->composition == kCompositionGPU) { 180d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema gpu_count++; 181d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 182d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 183d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->request.flags.tone_map) { 184d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGV_IF(kTagClient, "Tonemapping for layer at index %d", i); 185d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema switch (layer->composition) { 186d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema case kCompositionGPUTarget: 187d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!gpu_count) { 188d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // When all layers are on FrameBuffer and if they do not update in the next draw cycle, 189d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // then SDM marks them for SDE Composition because the cached FB layer gets displayed. 190d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer. 191d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer. 192d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) { 193d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_)); 194d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer); 195d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->layer_index_ = INT(i); 196d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->acquired_ = true; 197d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return 0; 198d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 199d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 200d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = AcquireToneMapSession(layer, &session_index); 201d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_ = INT(session_index); 202d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 203d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema default: 204d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = AcquireToneMapSession(layer, &session_index); 205d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 206d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 207d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 208d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 209d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Terminate(); 210d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return -1; 211d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 212d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 213d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = tone_map_sessions_.at(session_index); 214d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMap(layer, session); 215d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI_IF(kTagClient, "Layer %d associated with session index %d", i, session_index); 216d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->layer_index_ = INT(i); 217d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 218d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 219d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 220d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return 0; 221d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 222d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 223d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) { 224d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapBlitContext ctx = {}; 225d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ctx.layer = layer; 226d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 227d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint8_t buffer_index = session->current_buffer_index_; 228d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int &release_fence_fd = session->release_fence_fd_[buffer_index]; 229d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 230d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // use and close the layer->input_buffer acquire fence fd. 231d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int acquire_fd = layer->input_buffer.acquire_fence_fd; 232d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd); 233d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 234d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (acquire_fd >= 0) { 235d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&acquire_fd); 236d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 237d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 238d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (release_fence_fd >= 0) { 239d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&release_fence_fd); 240d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 241d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 242d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DTRACE_BEGIN("GPU_TM_BLIT"); 243d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx); 244d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DTRACE_END(); 245d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 246d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DumpToneMapOutput(session, &ctx.fence_fd); 247d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer); 248d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 249d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 250d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::PostCommit(LayerStack *layer_stack) { 251d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema auto it = tone_map_sessions_.begin(); 252d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema while (it != tone_map_sessions_.end()) { 253d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t session_index = UINT32(std::distance(tone_map_sessions_.begin(), it)); 254d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = tone_map_sessions_.at(session_index); 255d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (session->acquired_) { 256d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Layer *layer = layer_stack->layers.at(UINT32(session->layer_index_)); 257d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Close the fd returned by GPU ToneMapper and set release fence. 258d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema LayerBuffer &layer_buffer = layer->input_buffer; 259d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&layer_buffer.acquire_fence_fd); 260d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->SetReleaseFence(layer_buffer.release_fence_fd); 261d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->acquired_ = false; 262d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema it++; 263d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } else { 264d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI_IF(kTagClient, "Tone map session %d closed.", session_index); 265d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 266d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema it = tone_map_sessions_.erase(it); 267d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int deleted_session = INT(session_index); 268d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // If FB tonemap session gets deleted, reset fb_session_index_, else update it. 269d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (deleted_session == fb_session_index_) { 270d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_ = -1; 271d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } else if (deleted_session < fb_session_index_) { 272d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_--; 273d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 274d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 275d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 276d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 277d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 278d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::Terminate() { 279d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (tone_map_sessions_.size()) { 280d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema while (!tone_map_sessions_.empty()) { 281d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete tone_map_sessions_.back(); 282d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_sessions_.pop_back(); 283d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 284d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_ = -1; 285d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 286d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 287d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 288d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::SetFrameDumpConfig(uint32_t count) { 289d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI("Dump FrameConfig count = %d", count); 290d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_count_ = count; 291d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_index_ = 0; 292d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 293d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 294d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) { 295d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = kErrorNone; 296d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!dump_frame_count_) { 297d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return; 298d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 299d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 300d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema BufferInfo &buffer_info = session->buffer_info_[session->current_buffer_index_]; 301d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema private_handle_t *target_buffer = static_cast<private_handle_t *>(buffer_info.private_data); 302d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 303d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (*acquire_fd >= 0) { 304d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int error = sync_wait(*acquire_fd, 1000); 305d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error < 0) { 306d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 307d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return; 308d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 309d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 310d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 311d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd); 312d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 313d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("MapBuffer failed, base addr = %x", target_buffer->base); 314d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return; 315d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 316d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 317d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema size_t result = 0; 318d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema char dump_file_name[PATH_MAX]; 319d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary" 320d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema "/tonemap_%dx%d_frame%d.raw", HWCDebugHandler::DumpDir(), target_buffer->width, 321d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema target_buffer->height, dump_frame_index_); 322d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 323d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FILE* fp = fopen(dump_file_name, "w+"); 324d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (fp) { 325d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI("base addr = %x", target_buffer->base); 326d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp); 327d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fclose(fp); 328d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 329d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_count_--; 330d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_index_++; 331d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(acquire_fd); 332d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 333d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 334d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaDisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) { 335d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // When the property vendor.display.disable_hdr_lut_gen is set, the lutEntries and gridEntries in 336d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut 337d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // for Tonemapping. 338d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) { 339d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Atleast lutEntries must be valid for GPU Tonemapper. 340d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Invalid Lut Entries or lut dimension = %d", layer->lut_3d.dim); 341d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorParameters; 342d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 343d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 344d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Check if we can re-use an existing tone map session. 345d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) { 346d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *tonemap_session = tone_map_sessions_.at(i); 347d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer)) { 348d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) % 349d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession::kNumIntermediateBuffers; 350d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tonemap_session->acquired_ = true; 351d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema *session_index = i; 352d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 353d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 354d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 355d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 356d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = new ToneMapSession(buffer_allocator_); 357d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!session) { 358d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorMemory; 359d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 360d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 361d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->SetToneMapConfig(layer); 362d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 363d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapGetInstanceContext ctx; 364d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ctx.layer = layer; 365d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx); 366d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 367d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (session->gpu_tone_mapper_ == NULL) { 368d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Get Tonemapper failed!"); 369d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 370d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNotSupported; 371d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 372d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = session->AllocateIntermediateBuffers(layer); 373d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 374d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Allocation of Intermediate Buffers failed!"); 375d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 376d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return error; 377d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 378d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 379d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->acquired_ = true; 380d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_sessions_.push_back(session); 381d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema *session_index = UINT32(tone_map_sessions_.size() - 1); 382d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 383d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 384d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 385d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 386d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} // namespace sdm 387