// 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 "RenderLibImpl.h"

#include "FrameBuffer.h"
#include "RendererImpl.h"
#include "aemu/base/files/Stream.h"
#include "host-common/address_space_device_control_ops.h"
#include "host-common/crash_reporter.h"
#include "host-common/dma_device.h"
#include "host-common/emugl_vm_operations.h"
#include "host-common/feature_control.h"
#include "host-common/logging.h"
#include "host-common/opengl/misc.h"
#include "host-common/sync_device.h"

#if GFXSTREAM_ENABLE_HOST_GLES
#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
#endif

namespace gfxstream {

void RenderLibImpl::setRenderer(SelectedRenderer renderer) {
    emugl::setRenderer(renderer);
}

void RenderLibImpl::setAvdInfo(bool phone, int api) {
    emugl::setAvdInfo(phone, api);
}

void RenderLibImpl::getGlesVersion(int* maj, int* min) {
    emugl::getGlesVersion(maj, min);
}

void RenderLibImpl::setLogger(emugl_logger_struct logger) {
#ifdef CONFIG_AEMU
    set_gfxstream_logger(logger.coarse);
    set_gfxstream_fine_logger(logger.fine);
#endif
}

void RenderLibImpl::setGraphicsObjectCounter(
        android::base::GraphicsObjectCounter* counter) {
    emugl::setGraphicsObjectCounter(counter);
}

void RenderLibImpl::setGLObjectCounter(
        android::base::GLObjectCounter* counter) {
    emugl::setGLObjectCounter(counter);
}

void RenderLibImpl::setCrashReporter(emugl_crash_reporter_t reporter) {
    // set_emugl_crash_reporter(reporter);
}

void RenderLibImpl::setFeatureController(emugl_feature_is_enabled_t featureController) {
    android::featurecontrol::setFeatureEnabledCallback(featureController);
}

void RenderLibImpl::setSyncDevice
    (emugl_sync_create_timeline_t create_timeline,
     emugl_sync_create_fence_t create_fence,
     emugl_sync_timeline_inc_t timeline_inc,
     emugl_sync_destroy_timeline_t destroy_timeline,
     emugl_sync_register_trigger_wait_t register_trigger_wait,
     emugl_sync_device_exists_t device_exists) {
    emugl::set_emugl_sync_create_timeline(create_timeline);
    emugl::set_emugl_sync_create_fence(create_fence);
    emugl::set_emugl_sync_timeline_inc(timeline_inc);
    emugl::set_emugl_sync_destroy_timeline(destroy_timeline);
    emugl::set_emugl_sync_register_trigger_wait(register_trigger_wait);
    emugl::set_emugl_sync_device_exists(device_exists);
}

void RenderLibImpl::setDmaOps(emugl_dma_ops ops) {
    emugl::set_emugl_dma_get_host_addr(ops.get_host_addr);
    emugl::set_emugl_dma_unlock(ops.unlock);
}

void RenderLibImpl::setVmOps(const QAndroidVmOperations &vm_operations) {
    set_emugl_vm_operations(vm_operations);
    address_space_set_vm_operations(&get_emugl_vm_operations());
}

void RenderLibImpl::setAddressSpaceDeviceControlOps(struct address_space_device_control_ops* ops) {
    set_emugl_address_space_device_control_ops(ops);
}

void RenderLibImpl::setWindowOps(const QAndroidEmulatorWindowAgent &window_operations,
                                 const QAndroidMultiDisplayAgent &multi_display_operations) {
    emugl::set_emugl_window_operations(window_operations);
    emugl::set_emugl_multi_display_operations(multi_display_operations);
}

void RenderLibImpl::setUsageTracker(android::base::CpuUsage* cpuUsage,
                                    android::base::MemoryTracker* memUsage) {
    emugl::setCpuUsage(cpuUsage);
    emugl::setMemoryTracker(memUsage);
}

void RenderLibImpl::setGrallocImplementation(GrallocImplementation gralloc) {
    emugl::setGrallocImplementation(gralloc);
}

bool RenderLibImpl::getOpt(RenderOpt* opt) {
    FrameBuffer* fb  = FrameBuffer::getFB();
    if (fb == nullptr) {
        return false;
    }

#if GFXSTREAM_ENABLE_HOST_GLES
    opt->display = fb->getDisplay();
    opt->surface = fb->getWindowSurface();
    opt->config = fb->getConfig();
#endif
    return (opt->display && opt->surface  && opt->config);
}

RendererPtr RenderLibImpl::initRenderer(int width, int height,
                                        gfxstream::host::FeatureSet features,
                                        bool useSubWindow, bool egl2egl) {
    if (!mRenderer.expired()) {
        return nullptr;
    }

    const auto res = std::make_shared<RendererImpl>();
    if (!res->initialize(width, height, features, useSubWindow, egl2egl)) {
        return nullptr;
    }
    mRenderer = res;
    return res;
}

static void impl_onLastCbRef(uint32_t handle) {
    FrameBuffer* fb = FrameBuffer::getFB();
    if (fb)
        fb->onLastColorBufferRef(handle);
}

OnLastColorBufferRef RenderLibImpl::getOnLastColorBufferRef() {
    return (OnLastColorBufferRef)impl_onLastCbRef;
}

}  // namespace gfxstream
