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