/*
 * Copyright (C) 2023 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.
 */

/*
 * Usually, display controllers do not use intermediate buffer for composition
 * results. Instead, they scan-out directly from the input buffers, composing
 * the planes on the fly every VSYNC.
 *
 * Flattening is a technique that reduces memory bandwidth and power consumption
 * by converting non-updating multi-plane composition into a single-plane.
 * Additionally, flattening also makes more shared planes available for use by
 * other CRTCs.
 *
 * If the client is not updating layers for 1 second, FlatCon triggers a
 * callback to refresh the screen. The compositor should mark all layers to be
 * composed by the client into a single framebuffer using GPU.
 */

#define LOG_TAG "drmhwc"

#include "FlatteningController.h"

#include "utils/log.h"

namespace android {

auto FlatteningController::CreateInstance(FlatConCallbacks &cbks)
    -> std::shared_ptr<FlatteningController> {
  auto fc = std::shared_ptr<FlatteningController>(new FlatteningController());

  /* Disable the controller by default as it can cause refresh event to be
   * issued at creation time, even when it is not required. This can fail VTS
   * tests at teardown that check for this behaviour. See:
   * https://cs.android.com/android/platform/superproject/main/+/cedca652b903e4f4e584e457b5a7038e0825fb94:hardware/interfaces/graphics/composer/aidl/vts/VtsComposerClient.cpp;drc=a2a6deaf5036e081f48379b6573db4465538b5ac;l=604
   */
  fc->Disable();
  fc->cbks_ = cbks;

  std::thread(&FlatteningController::ThreadFn, fc).detach();

  return fc;
}

/* Compositor should call this every frame */
bool FlatteningController::NewFrame() {
  bool wake_it = false;
  auto lock = std::lock_guard<std::mutex>(mutex_);

  if (flatten_next_frame_) {
    flatten_next_frame_ = false;
    return true;
  }

  sleep_until_ = std::chrono::system_clock::now() + kTimeout;
  if (disabled_) {
    wake_it = true;
    disabled_ = false;
  }

  if (wake_it)
    cv_.notify_all();

  return false;
}

void FlatteningController::ThreadFn(
    const std::shared_ptr<FlatteningController> &fc) {
  for (;;) {
    std::unique_lock<std::mutex> lock(fc->mutex_);
    if (fc.use_count() == 1 || !fc->cbks_.trigger)
      break;

    if (fc->sleep_until_ <= std::chrono::system_clock::now() &&
        !fc->disabled_) {
      fc->disabled_ = true;
      fc->flatten_next_frame_ = true;
      ALOGV("Timeout. Sending an event to compositor");
      fc->cbks_.trigger();
    }

    if (fc->disabled_) {
      ALOGV("Wait");
      fc->cv_.wait(lock);
    } else {
      ALOGV("Wait_until");
      fc->cv_.wait_until(lock, fc->sleep_until_);
    }
  }
}

}  // namespace android
