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