Skip to content

Commit

Permalink
Merge "sdm: Use sync task utility for hdr tonemapping."
Browse files Browse the repository at this point in the history
  • Loading branch information
lnxbuild authored and Gerrit - the friendly Code Review server committed Jun 13, 2017
2 parents 4769705 + 1b1d55e commit bd80422
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 115 deletions.
128 changes: 34 additions & 94 deletions sdm/libs/hwc2/hwc_tonemapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,104 +47,50 @@

namespace sdm {

ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator) :
buffer_allocator_(buffer_allocator) {
ToneMapSession::ToneMapSession(HWCBufferAllocator *buffer_allocator)
: tone_map_task_(*this), buffer_allocator_(buffer_allocator) {
buffer_info_.resize(kNumIntermediateBuffers);
}

ToneMapSession::~ToneMapSession() {
ProcessEvent(kEventExit);
worker_thread_.join();

delete gpu_tone_mapper_;
gpu_tone_mapper_ = nullptr;
tone_map_task_.ScheduleTask(ToneMapTaskCode::kCodeDestroy);
FreeIntermediateBuffers();
buffer_info_.clear();
}

void ToneMapSession::Init() {
std::thread thread(ToneMapThread, this);
worker_thread_.swap(thread);
}

void ToneMapSession::ToneMapThread(ToneMapSession *session) {
if (session) {
session->ToneMapHandler();
}
}

void ToneMapSession::NotifyClient() {
// Notify Main thread that worker is ready for events.
std::unique_lock<std::mutex> main_lock(main_mutex_);
main_condition_.notify_one();
}

void ToneMapSession::ToneMapHandler() {
// Acquire worker lock and start waiting for events.
// Wait must be started before caller thread can post events,
// otherwise posted events will be lost.
std::unique_lock<std::mutex> worker_lock(worker_mutex_);
// Notify main thread and ensure that main thread mutex is
// unlocked before moving further.
NotifyClient();

while(tone_map_event_ != kEventExit) {
worker_condition_.wait(worker_lock);

// Start Processing Commands.
switch (tone_map_event_) {
case kEventBlit: {
uint8_t buffer_index = current_buffer_index_;
const void *dst_hnd = reinterpret_cast<const void *>
(buffer_info_[buffer_index].private_data);
const void *src_hnd = reinterpret_cast<const void *>(layer_->input_buffer.buffer_id);
*fence_fd_ = gpu_tone_mapper_->blit(dst_hnd,src_hnd, merged_fd_);
}
break;
case kEventGetInstance: {
Color10Bit *grid_entries = NULL;
int grid_size = 0;
if (layer_->lut_3d.validGridEntries) {
grid_entries = layer_->lut_3d.gridEntries;
grid_size = INT(layer_->lut_3d.gridSize);
}
gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
layer_->lut_3d.lutEntries,
layer_->lut_3d.dim,
grid_entries, grid_size);
void ToneMapSession::OnTask(const ToneMapTaskCode &task_code) {
switch (task_code) {
case ToneMapTaskCode::kCodeGetInstance: {
Color10Bit *grid_entries = NULL;
int grid_size = 0;
if (layer_->lut_3d.validGridEntries) {
grid_entries = layer_->lut_3d.gridEntries;
grid_size = INT(layer_->lut_3d.gridSize);
}
break;
case kEventExit:
break;
case kEventNone:
break;
}

if (tone_map_event_ == kEventNone) {
// Check if event is Spurious.
continue;
} else if (tone_map_event_ != kEventExit) {
// Reset handled event.
tone_map_event_ = kEventNone;
}
gpu_tone_mapper_ = TonemapperFactory_GetInstance(tone_map_config_.type,
layer_->lut_3d.lutEntries,
layer_->lut_3d.dim,
grid_entries, grid_size);
}
break;

case ToneMapTaskCode::kCodeBlit: {
uint8_t buffer_index = current_buffer_index_;
const void *dst_hnd = reinterpret_cast<const void *>
(buffer_info_[buffer_index].private_data);
const void *src_hnd = reinterpret_cast<const void *>(layer_->input_buffer.buffer_id);
*fence_fd_ = gpu_tone_mapper_->blit(dst_hnd,src_hnd, merged_fd_);
}
break;

std::unique_lock<std::mutex> main_lock(main_mutex_);
// Notify completion of current job to main thread
// and start waiting for new event after notification.
main_condition_.notify_one();
}
}
case ToneMapTaskCode::kCodeDestroy: {
delete gpu_tone_mapper_;
}
break;

void ToneMapSession::ProcessEvent(ToneMapEvent event) {
std::unique_lock<std::mutex> main_lock(main_mutex_);
{
// Ensure that worker is waiting for events.
std::unique_lock<std::mutex> worker_lock(worker_mutex_);
tone_map_event_ = event;
worker_condition_.notify_one();
default:
break;
}
// Wait until worker signals.
main_condition_.wait(main_lock);
}

DisplayError ToneMapSession::AllocateIntermediateBuffers(const Layer *layer) {
Expand Down Expand Up @@ -289,7 +235,7 @@ void HWCToneMapper::ToneMap(Layer* layer, ToneMapSession *session) {
session->fence_fd_ = &fence_fd;

DTRACE_BEGIN("GPU_TM_BLIT");
session->ProcessEvent(kEventBlit);
session->tone_map_task_.ScheduleTask(ToneMapTaskCode::kCodeBlit);
DTRACE_END();

DumpToneMapOutput(session, &fence_fd);
Expand Down Expand Up @@ -400,14 +346,8 @@ DisplayError HWCToneMapper::AcquireToneMapSession(Layer *layer, uint32_t *sessio
return kErrorMemory;
}

{
std::unique_lock<std::mutex> main_lock(session->main_mutex_);
session->Init();
session->main_condition_.wait(main_lock);
}

session->layer_ = layer;
session->ProcessEvent(kEventGetInstance);
session->tone_map_task_.ScheduleTask(ToneMapTaskCode::kCodeGetInstance);

session->SetToneMapConfig(layer);

Expand Down
30 changes: 9 additions & 21 deletions sdm/libs/hwc2/hwc_tonemapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@
#include <hardware/hwcomposer.h>
#include <core/layer_stack.h>
#include <utils/sys.h>
#include <utils/sync_task.h>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>

#include "hwc_buffer_sync_handler.h"
#include "hwc_buffer_allocator.h"
Expand All @@ -47,11 +45,10 @@ class Tonemapper;

namespace sdm {

enum ToneMapEvent {
kEventNone,
kEventGetInstance,
kEventBlit,
kEventExit,
enum class ToneMapTaskCode : int32_t {
kCodeGetInstance,
kCodeBlit,
kCodeDestroy,
};

struct ToneMapConfig {
Expand All @@ -62,31 +59,23 @@ struct ToneMapConfig {
bool secure = false;
};

class ToneMapSession {
class ToneMapSession : public SyncTask<ToneMapTaskCode>::TaskHandler {
public:
explicit ToneMapSession(HWCBufferAllocator *buffer_allocator);
~ToneMapSession();
void Init();
DisplayError AllocateIntermediateBuffers(const Layer *layer);
void FreeIntermediateBuffers();
void UpdateBuffer(int acquire_fence, LayerBuffer *buffer);
void SetReleaseFence(int fd);
void SetToneMapConfig(Layer *layer);
bool IsSameToneMapConfig(Layer *layer);

// worker thread for gles operations
static void ToneMapThread(ToneMapSession *session);
void ToneMapHandler();
void NotifyClient();
void ProcessEvent(ToneMapEvent event);
// TaskHandler methods implementation.
virtual void OnTask(const ToneMapTaskCode &task_code);

static const uint8_t kNumIntermediateBuffers = 2;
std::thread worker_thread_;
std::mutex main_mutex_;
std::condition_variable main_condition_;
std::mutex worker_mutex_;
std::condition_variable worker_condition_;

SyncTask<ToneMapTaskCode> tone_map_task_;
Tonemapper *gpu_tone_mapper_ = nullptr;
HWCBufferAllocator *buffer_allocator_ = nullptr;
ToneMapConfig tone_map_config_ = {};
Expand All @@ -95,7 +84,6 @@ class ToneMapSession {
int release_fence_fd_[kNumIntermediateBuffers] = {-1, -1};
bool acquired_ = false;
int layer_index_ = -1;
ToneMapEvent tone_map_event_ = kEventNone;
Layer *layer_ = nullptr;
int *fence_fd_ = nullptr;
int merged_fd_ = -1;
Expand Down

0 comments on commit bd80422

Please sign in to comment.