14a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*
24a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
34a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*
44a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* Redistribution and use in source and binary forms, with or without
54a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* modification, are permitted provided that the following conditions are
64a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* met:
74a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*  * Redistributions of source code must retain the above copyright
84a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    notice, this list of conditions and the following disclaimer.
94a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*  * Redistributions in binary form must reproduce the above
104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    copyright notice, this list of conditions and the following
114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    disclaimer in the documentation and/or other materials provided
124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    with the distribution.
134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*  * Neither the name of The Linux Foundation nor the names of its
144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    contributors may be used to endorse or promote products derived
154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*    from this software without specific prior written permission.
164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*
174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh*/
294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <gralloc_priv.h>
314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sync/sync.h>
324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <TonemapFactory.h>
344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <core/buffer_allocator.h>
364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/constants.h>
384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/debug.h>
394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/formats.h>
404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/rect.h>
414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <utils/utils.h>
424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <vector>
444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hwc_debugger.h"
464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "hwc_tonemapper.h"
474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define __CLASS__ "HWCToneMapper"
494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhnamespace sdm {
514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  : tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer_info_.resize(kNumIntermediateBuffers);
554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhToneMapSession::~ToneMapSession() {
584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_task_.PerformTask(ToneMapTaskCode::kCodeDestroy, nullptr);
594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  FreeIntermediateBuffers();
604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer_info_.clear();
614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid ToneMapSession::OnTask(const ToneMapTaskCode &task_code,
644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                            SyncTask<ToneMapTaskCode>::TaskContext *task_context) {
654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  switch (task_code) {
664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case ToneMapTaskCode::kCodeGetInstance: {
674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ToneMapGetInstanceContext *ctx = static_cast<ToneMapGetInstanceContext *>(task_context);
684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        Lut3d &lut_3d = ctx->layer->lut_3d;
694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        Color10Bit *grid_entries = NULL;
704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        int grid_size = 0;
714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (lut_3d.validGridEntries) {
724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          grid_entries = lut_3d.gridEntries;
734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          grid_size = INT(lut_3d.gridSize);
744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                         lut_3d.lutEntries, lut_3d.dim,
774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                         grid_entries, grid_size,
784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                         tone_map_config_.secure);
794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case ToneMapTaskCode::kCodeBlit: {
834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ToneMapBlitContext *ctx = static_cast<ToneMapBlitContext *>(task_context);
844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        uint8_t buffer_index = current_buffer_index_;
854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        const void *dst_hnd = reinterpret_cast<const void *>
864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                (buffer_info_[buffer_index].private_data);
874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        const void *src_hnd = reinterpret_cast<const void *>
884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                (ctx->layer->input_buffer.buffer_id);
894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->fence_fd = gpu_tone_mapper_->blit(dst_hnd, src_hnd, ctx->merged_fd);
904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    case ToneMapTaskCode::kCodeDestroy: {
944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete gpu_tone_mapper_;
954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    default:
994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      break;
1004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
1014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
1044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError error = kErrorNone;
1054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
1064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    BufferInfo &buffer_info = buffer_info_[i];
1074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    buffer_info.buffer_config.width = layer->request.width;
1084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    buffer_info.buffer_config.height = layer->request.height;
1094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    buffer_info.buffer_config.format = layer->request.format;
1104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    buffer_info.buffer_config.secure = layer->request.flags.secure;
1114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    buffer_info.buffer_config.gfx_client = true;
1124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    error = buffer_allocator_->AllocateBuffer(&buffer_info);
1134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (error != kErrorNone) {
1144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      FreeIntermediateBuffers();
1154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return error;
1164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
1174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
1184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
1204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid ToneMapSession::FreeIntermediateBuffers() {
1234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint8_t i = 0; i < kNumIntermediateBuffers; i++) {
1244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Free the valid fence
1254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (release_fence_fd_[i] >= 0) {
1264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      CloseFd(&release_fence_fd_[i]);
1274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
1284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    BufferInfo &buffer_info = buffer_info_[i];
1294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (buffer_info.private_data) {
1304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      buffer_allocator_->FreeBuffer(&buffer_info);
1314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
1324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
1334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid ToneMapSession::UpdateBuffer(int acquire_fence, LayerBuffer *buffer) {
1364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // Acquire fence will be closed by HWC Display.
1374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // Fence returned by GPU will be closed in PostCommit.
1384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer->acquire_fence_fd = acquire_fence;
1394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer->size = buffer_info_[current_buffer_index_].alloc_buffer_info.size;
1404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer->planes[0].fd = buffer_info_[current_buffer_index_].alloc_buffer_info.fd;
1414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid ToneMapSession::SetReleaseFence(int fd) {
1444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  CloseFd(&release_fence_fd_[current_buffer_index_]);
1454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // Used to give to GPU tonemapper along with input layer fd
1464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  release_fence_fd_[current_buffer_index_] = dup(fd);
1474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid ToneMapSession::SetToneMapConfig(Layer *layer) {
1504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // HDR -> SDR is FORWARD and SDR - > HDR is INVERSE
1514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_config_.type = layer->input_buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
1524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_config_.colorPrimaries = layer->input_buffer.color_metadata.colorPrimaries;
1534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_config_.transfer = layer->input_buffer.color_metadata.transfer;
1544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_config_.secure = layer->request.flags.secure;
1554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_config_.format = layer->request.format;
1564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhbool ToneMapSession::IsSameToneMapConfig(Layer *layer) {
1594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  LayerBuffer& buffer = layer->input_buffer;
1604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  private_handle_t *handle = static_cast<private_handle_t *>(buffer_info_[0].private_data);
1614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int tonemap_type = buffer.flags.hdr ? TONEMAP_FORWARD : TONEMAP_INVERSE;
1624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return ((tonemap_type == tone_map_config_.type) &&
1644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (buffer.color_metadata.colorPrimaries == tone_map_config_.colorPrimaries) &&
1654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (buffer.color_metadata.transfer == tone_map_config_.transfer) &&
1664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (layer->request.flags.secure == tone_map_config_.secure) &&
1674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (layer->request.format == tone_map_config_.format) &&
1684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (layer->request.width == UINT32(handle->unaligned_width)) &&
1694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          (layer->request.height == UINT32(handle->unaligned_height)));
1704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhint HWCToneMapper::HandleToneMap(LayerStack *layer_stack) {
1734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint32_t gpu_count = 0;
1744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError error = kErrorNone;
1754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
1774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint32_t session_index = 0;
1784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    Layer *layer = layer_stack->layers.at(i);
1794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (layer->composition == kCompositionGPU) {
1804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      gpu_count++;
1814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
1824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (layer->request.flags.tone_map) {
1844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      switch (layer->composition) {
1854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      case kCompositionGPUTarget:
1864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (!gpu_count) {
1874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          // When all layers are on FrameBuffer and if they do not update in the next draw cycle,
1884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          // then SDM marks them for SDE Composition because the cached FB layer gets displayed.
1894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          // GPU count will be 0 in this case. Try to use the existing tone-mapped frame buffer.
1904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          // No ToneMap/Blit is required. Just update the buffer & acquire fence fd of FB layer.
1914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          if (!tone_map_sessions_.empty() && (fb_session_index_ >= 0)) {
1924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ToneMapSession *fb_tone_map_session = tone_map_sessions_.at(UINT32(fb_session_index_));
1934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            fb_tone_map_session->UpdateBuffer(-1 /* acquire_fence */, &layer->input_buffer);
1944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            fb_tone_map_session->layer_index_ = INT(i);
1954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            fb_tone_map_session->acquired_ = true;
1964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return 0;
1974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh          }
1984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
1994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        error = AcquireToneMapSession(layer, &session_index);
2004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        fb_session_index_ = INT(session_index);
2014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        break;
2024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      default:
2034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        error = AcquireToneMapSession(layer, &session_index);
2044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        break;
2054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
2064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (error != kErrorNone) {
2084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        Terminate();
2094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -1;
2104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
2114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      ToneMapSession *session = tone_map_sessions_.at(session_index);
2134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      ToneMap(layer, session);
2144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      session->layer_index_ = INT(i);
2154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return 0;
2194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
2224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ToneMapBlitContext ctx = {};
2234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ctx.layer = layer;
2244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  uint8_t buffer_index = session->current_buffer_index_;
2264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int &release_fence_fd = session->release_fence_fd_[buffer_index];
2274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // use and close the layer->input_buffer acquire fence fd.
2294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  int acquire_fd = layer->input_buffer.acquire_fence_fd;
2304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  buffer_sync_handler_.SyncMerge(release_fence_fd, acquire_fd, &ctx.merged_fd);
2314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (acquire_fd >= 0) {
2334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    CloseFd(&acquire_fd);
2344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (release_fence_fd >= 0) {
2374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    CloseFd(&release_fence_fd);
2384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_BEGIN("GPU_TM_BLIT");
2414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeBlit, &ctx);
2424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DTRACE_END();
2434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DumpToneMapOutput(session, &ctx.fence_fd);
2454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  session->UpdateBuffer(ctx.fence_fd, &layer->input_buffer);
2464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWCToneMapper::PostCommit(LayerStack *layer_stack) {
2494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  auto it = tone_map_sessions_.begin();
2504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  while (it != tone_map_sessions_.end()) {
2514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint32_t session_index = UINT32(std::distance(tone_map_sessions_.begin(), it));
2524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ToneMapSession *session = tone_map_sessions_.at(session_index);
2534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (session->acquired_) {
2544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      Layer *layer = layer_stack->layers.at(UINT32(session->layer_index_));
2554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      // Close the fd returned by GPU ToneMapper and set release fence.
2564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      LayerBuffer &layer_buffer = layer->input_buffer;
2574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      CloseFd(&layer_buffer.acquire_fence_fd);
2584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      session->SetReleaseFence(layer_buffer.release_fence_fd);
2594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      session->acquired_ = false;
2604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      it++;
2614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
2624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      delete session;
2634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      it = tone_map_sessions_.erase(it);
2644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      int deleted_session = INT(session_index);
2654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      // If FB tonemap session gets deleted, reset fb_session_index_, else update it.
2664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      if (deleted_session == fb_session_index_) {
2674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        fb_session_index_ = -1;
2684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      } else if (deleted_session < fb_session_index_) {
2694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        fb_session_index_--;
2704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      }
2714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWCToneMapper::Terminate() {
2764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (tone_map_sessions_.size()) {
2774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    while (!tone_map_sessions_.empty()) {
2784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      delete tone_map_sessions_.back();
2794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      tone_map_sessions_.pop_back();
2804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    fb_session_index_ = -1;
2824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWCToneMapper::SetFrameDumpConfig(uint32_t count) {
2864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DLOGI("Dump FrameConfig count = %d", count);
2874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  dump_frame_count_ = count;
2884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  dump_frame_index_ = 0;
2894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid HWCToneMapper::DumpToneMapOutput(ToneMapSession *session, int *acquire_fd) {
2924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError error = kErrorNone;
2934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!dump_frame_count_) {
2944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
2954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
2964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  BufferInfo &buffer_info = session->buffer_info_[session->current_buffer_index_];
2984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  private_handle_t *target_buffer = static_cast<private_handle_t *>(buffer_info.private_data);
2994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (*acquire_fd >= 0) {
3014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int error = sync_wait(*acquire_fd, 1000);
3024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (error < 0) {
3034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
3044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return;
3054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  error = buffer_allocator_->MapBuffer(target_buffer, *acquire_fd);
3094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (error != kErrorNone) {
3104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("MapBuffer failed, base addr = %x", target_buffer->base);
3114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return;
3124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  size_t result = 0;
3154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  char dump_file_name[PATH_MAX];
3164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  snprintf(dump_file_name, sizeof(dump_file_name), "%s/frame_dump_primary"
3174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh           "/tonemap_%dx%d_frame%d.raw", HWCDebugHandler::DumpDir(), target_buffer->width,
3184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh           target_buffer->height, dump_frame_index_);
3194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  FILE* fp = fopen(dump_file_name, "w+");
3214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (fp) {
3224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGI("base addr = %x", target_buffer->base);
3234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp);
3244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    fclose(fp);
3254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  dump_frame_count_--;
3274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  dump_frame_index_++;
3284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  CloseFd(acquire_fd);
3294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhDisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *session_index) {
3324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // When the property sdm.disable_hdr_lut_gen is set, the lutEntries and gridEntries in
3334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // the Lut3d will be NULL, clients needs to allocate the memory and set correct 3D Lut
3344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // for Tonemapping.
3354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!layer->lut_3d.lutEntries || !layer->lut_3d.dim) {
3364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Atleast lutEntries must be valid for GPU Tonemapper.
3374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Invalid Lut Entries or lut dimension = %d", layer->lut_3d.dim);
3384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorParameters;
3394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  // Check if we can re-use an existing tone map session.
3424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  for (uint32_t i = 0; i < tone_map_sessions_.size(); i++) {
3434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ToneMapSession *tonemap_session = tone_map_sessions_.at(i);
3444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!tonemap_session->acquired_ && tonemap_session->IsSameToneMapConfig(layer)) {
3454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      tonemap_session->current_buffer_index_ = (tonemap_session->current_buffer_index_ + 1) %
3464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                ToneMapSession::kNumIntermediateBuffers;
3474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      tonemap_session->acquired_ = true;
3484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      *session_index = i;
3494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh      return kErrorNone;
3504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ToneMapSession *session = new ToneMapSession(buffer_allocator_);
3544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (!session) {
3554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorMemory;
3564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  session->SetToneMapConfig(layer);
3594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ToneMapGetInstanceContext ctx;
3614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  ctx.layer = layer;
3624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  session->tone_map_task_.PerformTask(ToneMapTaskCode::kCodeGetInstance, &ctx);
3634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (session->gpu_tone_mapper_ == NULL) {
3654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Get Tonemapper failed!");
3664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    delete session;
3674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return kErrorNotSupported;
3684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  DisplayError error = session->AllocateIntermediateBuffers(layer);
3704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  if (error != kErrorNone) {
3714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    DLOGE("Allocation of Intermediate Buffers failed!");
3724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    delete session;
3734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return error;
3744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  }
3754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  session->acquired_ = true;
3774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  tone_map_sessions_.push_back(session);
3784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  *session_index = UINT32(tone_map_sessions_.size() - 1);
3794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh  return kErrorNone;
3814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}  // namespace sdm
384