1d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema/* 2d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema* Copyright (c) 2016 - 2017, 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 <alloc_controller.h> 31d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <gr.h> 32d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <gralloc_priv.h> 33d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <memalloc.h> 34d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <sync/sync.h> 35d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 36d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <TonemapFactory.h> 37d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 38d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <core/buffer_allocator.h> 39d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 40d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/constants.h> 41d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/debug.h> 42d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/formats.h> 43d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/rect.h> 44d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <utils/utils.h> 45d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 46d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include <vector> 47d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 48d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_debugger.h" 49d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#include "hwc_tonemapper.h" 50d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 51d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema#define __CLASS__ "HWCToneMapper" 52d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 53d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemanamespace sdm { 54d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 55d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaToneMapSession::~ToneMapSession() { 56d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete gpu_tone_mapper_; 57d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema gpu_tone_mapper_ = NULL; 58d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FreeIntermediateBuffers(); 59d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 60d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 61d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaDisplayError ToneMapSession::AllocateIntermediateBuffers(int w, int h, int format, int usage) { 62d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) { 63d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int status = alloc_buffer(&intermediate_buffer_[i], w, h, format, usage); 64d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (status < 0) { 65d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FreeIntermediateBuffers(); 66d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorMemory; 67d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 68d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 69d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 70d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 71d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 72d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 73d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::FreeIntermediateBuffers() { 74d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) { 75d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema private_handle_t *buffer = intermediate_buffer_[i]; 76d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (buffer) { 77d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Free the valid fence 78d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (release_fence_fd_[i] >= 0) { 79d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&release_fence_fd_[i]); 80d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 81d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema free_buffer(buffer); 82d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema intermediate_buffer_[i] = NULL; 83d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 84d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 85d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 86d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 87d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::UpdateBuffer(int acquire_fence, LayerBuffer *buffer) { 88d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Acquire fence will be closed by HWC Display. 89d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Fence returned by GPU will be closed in PostCommit. 90d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->acquire_fence_fd = acquire_fence; 91d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->size = intermediate_buffer_[current_buffer_index_]->size; 92d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer->planes[0].fd = intermediate_buffer_[current_buffer_index_]->fd; 93d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 94d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 95d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::SetReleaseFence(int fd) { 96d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&release_fence_fd_[current_buffer_index_]); 97d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Used to give to GPU tonemapper along with input layer fd 98d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema release_fence_fd_[current_buffer_index_] = dup(fd); 99d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 100d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 101d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid ToneMapSession::SetToneMapConfig(Layer *layer) { 102d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE 103d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; 104d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.colorPrimaries = layer->input_buffer.color_metadata.colorPrimaries; 105d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer; 106d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.secure = layer->request.flags.secure; 107d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_config_.format = layer->request.format; 108d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 109d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 110d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemabool ToneMapSession::IsSameToneMapConfig(Layer *layer) { 111d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema LayerBuffer& buffer = layer->input_buffer; 112d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema private_handle_t *handle = intermediate_buffer_[0]; 113d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE; 114d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 115d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return ((tonemap_type == tone_map_config_.type) && 116d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (buffer.color_metadata.colorPrimaries == tone_map_config_.colorPrimaries) && 117d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (buffer.color_metadata.transfer == tone_map_config_.transfer) && 118d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.flags.secure == tone_map_config_.secure) && 119d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.format == tone_map_config_.format) && 120d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.width == UINT32(handle->unaligned_width)) && 121d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema (layer->request.height == UINT32(handle->unaligned_height))); 122d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 123d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 124d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemaint HWCToneMapper::HandleToneMap(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) { 125d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t gpu_count = 0; 126d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = kErrorNone; 127d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 128d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint32_t i = 0; i < layer_stack->layers.size(); i++) { 129d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t session_index = 0; 130d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Layer *layer = layer_stack->layers.at(i); 131d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->composition == kCompositionGPU) { 132d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema gpu_count++; 133d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 134d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 135d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->request.flags.tone_map) { 136d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema switch (layer->composition) { 137d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema case kCompositionGPUTarget: 138d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!gpu_count) { 139d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // When all layers are on FrameBuffer and if they do not update in the next draw cycle, 140d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // then SDM marks them for SDE Composition because the cached FB layer gets displayed. 141d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer. 142d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer. 143d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!tone_map_sessions_.empty()) { 144d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(fb_session_index_); 145d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer); 146d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->layer_index_ = INT(i); 147d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_tone_map_session->acquired_ = true; 148d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return 0; 149d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 150d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 151d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = AcquireToneMapSession(layer, &session_index); 152d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_ = session_index; 153d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 154d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema default: 155d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = AcquireToneMapSession(layer, &session_index); 156d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema break; 157d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 158d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 159d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 160d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Terminate(); 161d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return -1; 162d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 163d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 164d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = tone_map_sessions_.at(session_index); 165d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMap(&content_list->hwLayers[i], layer, session); 166d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->layer_index_ = INT(i); 167d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 168d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 169d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 170d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return 0; 171d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 172d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 173d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::ToneMap(hwc_layer_1_t *hwc_layer, Layer* layer, ToneMapSession *session) { 174d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int fence_fd = -1; 175d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int acquire_fd = -1; 176d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int merged_fd = -1; 177d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 178d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint8_t buffer_index = session->current_buffer_index_; 179d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema const private_handle_t *dst_hnd = session->intermediate_buffer_[buffer_index]; 180d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema const private_handle_t *src_hnd = static_cast<const private_handle_t *>(hwc_layer->handle); 181d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 182d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema acquire_fd = dup(layer->input_buffer.acquire_fence_fd); 183d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema buffer_sync_handler_.SyncMerge(session->release_fence_fd_[buffer_index], acquire_fd, &merged_fd); 184d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 185d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (acquire_fd >= 0) { 186d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&acquire_fd); 187d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 188d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 189d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (session->release_fence_fd_[buffer_index] >= 0) { 190d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&session->release_fence_fd_[buffer_index]); 191d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 192d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 193d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DTRACE_BEGIN("GPU_TM_BLIT"); 194d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fence_fd = session->gpu_tone_mapper_->blit(reinterpret_cast<const void *>(dst_hnd), 195d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema reinterpret_cast<const void *>(src_hnd), merged_fd); 196d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DTRACE_END(); 197d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 198d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DumpToneMapOutput(session, &fence_fd); 199d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->UpdateBuffer(fence_fd, &layer->input_buffer); 200d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 201d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 202d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::PostCommit(LayerStack *layer_stack) { 203d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema auto it = tone_map_sessions_.begin(); 204d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema while (it != tone_map_sessions_.end()) { 205d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema uint32_t session_index = UINT32(std::distance(tone_map_sessions_.begin(), it)); 206d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = tone_map_sessions_.at(session_index); 207d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Layer *layer = layer_stack->layers.at(UINT32(session->layer_index_)); 208d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (session->acquired_) { 209d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Close the fd returned by GPU ToneMapper and set release fence. 210d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema LayerBuffer &layer_buffer = layer->input_buffer; 211d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(&layer_buffer.acquire_fence_fd); 212d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->SetReleaseFence(layer_buffer.release_fence_fd); 213d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->acquired_ = false; 214d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema it++; 215d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } else { 216d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 217d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema it = tone_map_sessions_.erase(it); 218d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 219d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 220d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 221d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 222d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::Terminate() { 223d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (tone_map_sessions_.size()) { 224d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema while (!tone_map_sessions_.empty()) { 225d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete tone_map_sessions_.back(); 226d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_sessions_.pop_back(); 227d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 228d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fb_session_index_ = 0; 229d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 230d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 231d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 232d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::SetFrameDumpConfig(uint32_t count) { 233d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI("Dump FrameConfig count = %d", count); 234d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_count_ = count; 235d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_index_ = 0; 236d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 237d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 238d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennemavoid HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) { 239d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!dump_frame_count_) { 240d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return; 241d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 242d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 243d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema private_handle_t *target_buffer = session->intermediate_buffer_[session->current_buffer_index_]; 244d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 245d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (*acquire_fd >= 0) { 246d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int error = sync_wait(*acquire_fd, 1000); 247d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error < 0) { 248d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); 249d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return; 250d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 251d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 252d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 253d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema size_t result = 0; 254d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema char dump_file_name[PATH_MAX]; 255d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary" 256d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema "/tonemap_%dx%d_frame%d.raw", target_buffer->width, target_buffer->height, 257d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_index_); 258d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 259d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema FILE* fp = fopen(dump_file_name, "w+"); 260d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (fp) { 261d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGI("base addr = %x", target_buffer->base); 262d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp); 263d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema fclose(fp); 264d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 265d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_count_--; 266d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema dump_frame_index_++; 267d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema CloseFd(acquire_fd); 268d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 269d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 270d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben FennemaDisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) { 271d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema Color10Bit *grid_entries = NULL; 272d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int grid_size = 0; 273d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 274d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->lut_3d.validGridEntries) { 275d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_entries = layer->lut_3d.gridEntries; 276d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_size = INT(layer->lut_3d.gridSize); 277d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 278d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 279d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in 280d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut 281d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // for Tonemapping. 282d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) { 283d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Atleast lutEntries must be valid for GPU Tonemapper. 284d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Invalid Lut Entries or lut dimension = %d", layer->lut_3d.dim); 285d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorParameters; 286d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 287d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 288d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema // Check if we can re-use an existing tone map session. 289d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) { 290d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *tonemap_session = tone_map_sessions_.at(i); 291d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer)) { 292d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) % 293d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession::kNumIntermediateBuffers; 294d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tonemap_session->acquired_ = true; 295d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema *session_index = i; 296d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 297d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 298d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 299d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 300d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema ToneMapSession *session = new ToneMapSession(); 301d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 302d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->SetToneMapConfig(layer); 303d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->gpu_tone_mapper_ = TonemapperFactory_GetInstance(session->tone_map_config_.type, 304d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema layer->lut_3d.lutEntries, 305d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema layer->lut_3d.dim, 306d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema grid_entries, grid_size, 307d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->tone_map_config_.secure); 308d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 309d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (session->gpu_tone_mapper_ == NULL) { 310d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Get Tonemapper failed!"); 311d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 312d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNotSupported; 313d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 314d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 315d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int status, format; 316d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DisplayError error = kErrorNone; 317d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema int usage = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE); 318d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 319d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (layer->request.flags.secure) { 320d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema usage = INT(GRALLOC_USAGE_PRIVATE_MM_HEAP); 321d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema usage |= INT(GRALLOC_USAGE_PROTECTED); 322d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 323d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 324d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema status = buffer_allocator_.SetBufferInfo(layer->request.format, &format, &usage); 325d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema error = session->AllocateIntermediateBuffers(INT(layer->request.width), 326d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema INT(layer->request.height), format, usage); 327d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 328d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema if (error != kErrorNone) { 329d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema DLOGE("Allocation of Intermediate Buffers failed!"); 330d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema delete session; 331d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return error; 332d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema } 333d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 334d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema session->acquired_ = true; 335d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema tone_map_sessions_.push_back(session); 336d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema *session_index = UINT32(tone_map_sessions_.size() - 1); 337d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 338d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema return kErrorNone; 339d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} 340d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema 341d39a514dd0540cf47e121775a77e9ac1b578bdb1Ben Fennema} // namespace sdm 342