/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "base_composer.h"

#include <string.h>

#include <log/log.h>
#include <hardware/gralloc.h>

#include "common/vsoc/lib/screen_region_view.h"
#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"

using vsoc::screen::ScreenRegionView;

namespace cvd {

namespace {

void BroadcastFrameBufferChanged(int index) {
  ScreenRegionView::GetInstance()->BroadcastNewFrame(
      static_cast<uint32_t>(index));
}

}  // namespace

BaseComposer::BaseComposer(int64_t vsync_base_timestamp,
                           int32_t vsync_period_ns)
    : vsync_base_timestamp_(vsync_base_timestamp),
      vsync_period_ns_(vsync_period_ns),
      fb_broadcaster_(BroadcastFrameBufferChanged) {
  hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
                reinterpret_cast<const hw_module_t**>(&gralloc_module_));
}

BaseComposer::~BaseComposer() {}

FbBroadcaster BaseComposer::ReplaceFbBroadcaster(FbBroadcaster fb_broadcaster) {
  FbBroadcaster tmp = fb_broadcaster_;
  fb_broadcaster_ = fb_broadcaster;
  return tmp;
}

void BaseComposer::Dump(char* buff __unused, int buff_len __unused) {}

void BaseComposer::Broadcast(int fb_index) {
  fb_broadcaster_(fb_index);
}

int BaseComposer::PostFrameBufferTarget(buffer_handle_t buffer_handle) {
  int fb_index = NextScreenBuffer();
  if (fb_index < 0) {
    ALOGE("Could not get the next buffer. Is the screen region large enough?");
    return -1;
  }
  auto screen_view = ScreenRegionView::GetInstance();
  void* frame_buffer = screen_view->GetBuffer(fb_index);
  const private_handle_t* p_handle =
      reinterpret_cast<const private_handle_t*>(buffer_handle);
  void* buffer;
  int retval = gralloc_module_->lock(gralloc_module_, buffer_handle,
                                     GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
                                     p_handle->x_res, p_handle->y_res, &buffer);
  if (retval != 0) {
    ALOGE("Got error code %d from lock function", retval);
    return -1;
  }
  memcpy(frame_buffer, buffer, screen_view->buffer_size());
  Broadcast(fb_index);
  return 0;
}  // namespace cvd

int BaseComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
  // find unsupported overlays
  for (size_t i = 0; i < num_layers; i++) {
    if (IS_TARGET_FRAMEBUFFER(layers[i].compositionType)) {
      continue;
    }
    layers[i].compositionType = HWC_FRAMEBUFFER;
  }
  return 0;
}

int BaseComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
  for (size_t idx = 0; idx < num_layers; idx++) {
    if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
      return PostFrameBufferTarget(layers[idx].handle);
    }
  }
  return -1;
}

int BaseComposer::NextScreenBuffer() {
  int num_buffers = ScreenRegionView::GetInstance()->number_of_buffers();
  last_frame_buffer_ =
      num_buffers > 0 ? (last_frame_buffer_ + 1) % num_buffers : -1;
  return last_frame_buffer_;
}

}  // namespace cvd
