/*
 * Copyright (C) 2013 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 "RenderProxy.h"

#include <SkBitmap.h>
#include <SkImage.h>
#include <SkPicture.h>
#include <gui/TraceUtils.h>
#include <pthread.h>
#include <ui/GraphicBufferAllocator.h>

#include "DeferredLayerUpdater.h"
#include "DisplayList.h"
#include "Properties.h"
#include "Readback.h"
#include "Rect.h"
#include "WebViewFunctorManager.h"
#include "renderthread/CanvasContext.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
#include "utils/Macros.h"
#include "utils/TimeUtils.h"

namespace android {
namespace uirenderer {
namespace renderthread {

RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
                         IContextFactory* contextFactory)
        : mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
#ifdef __ANDROID__
    pid_t uiThreadId = pthread_gettid_np(pthread_self());
#else
    pid_t uiThreadId = 0;
#endif
    pid_t renderThreadId = getRenderThreadTid();
    mContext = mRenderThread.queue().runSync([=, this]() -> CanvasContext* {
        CanvasContext* context = CanvasContext::create(mRenderThread, translucent, rootRenderNode,
                                                       contextFactory, uiThreadId, renderThreadId);
        if (context != nullptr) {
            mRenderThread.queue().post([=] { context->startHintSession(); });
        }
        return context;
    });
    mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}

RenderProxy::~RenderProxy() {
    destroyContext();
}

void RenderProxy::destroyContext() {
    if (mContext) {
        mDrawFrameTask.setContext(nullptr, nullptr, nullptr);
        // This is also a fence as we need to be certain that there are no
        // outstanding mDrawFrame tasks posted before it is destroyed
        mRenderThread.queue().runSync([this]() { delete mContext; });
        mContext = nullptr;
    }
}

void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
    mRenderThread.queue().post([this, swapBehavior]() { mContext->setSwapBehavior(swapBehavior); });
}

bool RenderProxy::loadSystemProperties() {
    return mRenderThread.queue().runSync([this]() -> bool {
        bool needsRedraw = Properties::load();
        if (mContext->profiler().consumeProperties()) {
            needsRedraw = true;
        }
        return needsRedraw;
    });
}

void RenderProxy::setName(const char* name) {
    // block since name/value pointers owned by caller
    // TODO: Support move arguments
    mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
}

void RenderProxy::setHardwareBuffer(AHardwareBuffer* buffer) {
#ifdef __ANDROID__
    if (buffer) {
        AHardwareBuffer_acquire(buffer);
    }
    mRenderThread.queue().post([this, hardwareBuffer = buffer]() mutable {
        mContext->setHardwareBuffer(hardwareBuffer);
        if (hardwareBuffer) {
            AHardwareBuffer_release(hardwareBuffer);
        }
    });
#endif
}

void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
    if (window) { ANativeWindow_acquire(window); }
    mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {
        mContext->setSurface(win, enableTimeout);
        if (win) { ANativeWindow_release(win); }
    });
}

void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
    auto funcs = mRenderThread.getASurfaceControlFunctions();
    if (surfaceControl) {
        funcs.acquireFunc(surfaceControl);
    }
    mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
        mContext->setSurfaceControl(control);
        if (control) {
            funcs.releaseFunc(control);
        }
    });
}

void RenderProxy::allocateBuffers() {
    mRenderThread.queue().post([this]() { mContext->allocateBuffers(); });
}

bool RenderProxy::pause() {
    return mRenderThread.queue().runSync([this]() -> bool { return mContext->pauseSurface(); });
}

void RenderProxy::setStopped(bool stopped) {
    mRenderThread.queue().runSync([this, stopped]() { mContext->setStopped(stopped); });
}

void RenderProxy::setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
    mRenderThread.queue().post(
            [=, this]() { mContext->setLightAlpha(ambientShadowAlpha, spotShadowAlpha); });
}

void RenderProxy::setLightGeometry(const Vector3& lightCenter, float lightRadius) {
    mRenderThread.queue().post(
            [=, this]() { mContext->setLightGeometry(lightCenter, lightRadius); });
}

void RenderProxy::setOpaque(bool opaque) {
    mRenderThread.queue().post([=, this]() { mContext->setOpaque(opaque); });
}

float RenderProxy::setColorMode(ColorMode mode) {
    // We only need to figure out what the renderer supports for HDR, otherwise this can stay
    // an async call since we already know the return value
    if (mode == ColorMode::Hdr || mode == ColorMode::Hdr10) {
        return mRenderThread.queue().runSync(
                [=, this]() -> float { return mContext->setColorMode(mode); });
    } else {
        mRenderThread.queue().post([=, this]() { mContext->setColorMode(mode); });
        return 1.f;
    }
}

void RenderProxy::setRenderSdrHdrRatio(float ratio) {
    mDrawFrameTask.setRenderSdrHdrRatio(ratio);
}

int64_t* RenderProxy::frameInfo() {
    return mDrawFrameTask.frameInfo();
}

void RenderProxy::forceDrawNextFrame() {
    mDrawFrameTask.forceDrawNextFrame();
}

int RenderProxy::syncAndDrawFrame() {
    return mDrawFrameTask.drawFrame();
}

void RenderProxy::destroy() {
    // destroyCanvasAndSurface() needs a fence as when it returns the
    // underlying BufferQueue is going to be released from under
    // the render thread.
    mRenderThread.queue().runSync([this]() { mContext->destroy(); });
}

void RenderProxy::destroyFunctor(int functor) {
    ATRACE_CALL();
    RenderThread& thread = RenderThread::getInstance();
    thread.queue().post([=]() { WebViewFunctorManager::instance().destroyFunctor(functor); });
}

DeferredLayerUpdater* RenderProxy::createTextureLayer() {
    return mRenderThread.queue().runSync([this]() -> auto {
        return mContext->createTextureLayer();
    });
}

void RenderProxy::buildLayer(RenderNode* node) {
    mRenderThread.queue().runSync([&]() { mContext->buildLayer(node); });
}

bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
    ATRACE_NAME("TextureView#getBitmap");
    auto& thread = RenderThread::getInstance();
    return thread.queue().runSync([&]() -> bool {
        return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success;
    });
}

void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
    mDrawFrameTask.pushLayerUpdate(layer);
}

void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
    mDrawFrameTask.removeLayerUpdate(layer);
}

void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
#ifdef __ANDROID__
    return mRenderThread.queue().runSync([&]() { layer->detachSurfaceTexture(); });
#endif
}

void RenderProxy::destroyHardwareResources() {
    return mRenderThread.queue().runSync([&]() { mContext->destroyHardwareResources(); });
}

void RenderProxy::trimMemory(int level) {
    // Avoid creating a RenderThread to do a trimMemory.
    if (RenderThread::hasInstance()) {
        RenderThread& thread = RenderThread::getInstance();
        const auto trimLevel = static_cast<TrimLevel>(level);
        thread.queue().post([&thread, trimLevel]() { thread.trimMemory(trimLevel); });
    }
}

void RenderProxy::trimCaches(int level) {
    // Avoid creating a RenderThread to do a trimMemory.
    if (RenderThread::hasInstance()) {
        RenderThread& thread = RenderThread::getInstance();
        const auto trimLevel = static_cast<CacheTrimLevel>(level);
        thread.queue().post([&thread, trimLevel]() { thread.trimCaches(trimLevel); });
    }
}

void RenderProxy::purgeCaches() {
    if (RenderThread::hasInstance()) {
        RenderThread& thread = RenderThread::getInstance();
        thread.queue().post([&thread]() {
            if (thread.getGrContext()) {
                thread.cacheManager().trimMemory(TrimLevel::COMPLETE);
            }
        });
    }
}

void RenderProxy::overrideProperty(const char* name, const char* value) {
    // expensive, but block here since name/value pointers owned by caller
    RenderThread::getInstance().queue().runSync(
            [&]() { Properties::overrideProperty(name, value); });
}

void RenderProxy::fence() {
    mRenderThread.queue().runSync([]() {});
}

int RenderProxy::maxTextureSize() {
    static int maxTextureSize = RenderThread::getInstance().queue().runSync(
            []() { return DeviceInfo::get()->maxTextureSize(); });
    return maxTextureSize;
}

void RenderProxy::stopDrawing() {
    mRenderThread.queue().runSync([this]() { mContext->stopDrawing(); });
}

void RenderProxy::notifyFramePending() {
    mRenderThread.queue().post([this]() { mContext->notifyFramePending(); });
}

void RenderProxy::notifyCallbackPending() {
    mRenderThread.queue().post([this]() { mContext->sendLoadResetHint(); });
}

void RenderProxy::notifyExpensiveFrame() {
    mRenderThread.queue().post([this]() { mContext->sendLoadIncreaseHint(); });
}

void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
    mRenderThread.queue().runSync([&]() {
        std::lock_guard lock(mRenderThread.getJankDataMutex());
        mContext->profiler().dumpData(fd);
        if (dumpFlags & DumpFlags::FrameStats) {
            mContext->dumpFrames(fd);
        }
        if (dumpFlags & DumpFlags::JankStats) {
            mRenderThread.globalProfileData()->dump(fd);
        }
        if (dumpFlags & DumpFlags::Reset) {
            mContext->resetFrameStats();
        }
    });
}

void RenderProxy::resetProfileInfo() {
    mRenderThread.queue().runSync([this]() {
        std::lock_guard lock(mRenderThread.getJankDataMutex());
        mContext->resetFrameStats();
    });
}

uint32_t RenderProxy::frameTimePercentile(int percentile) {
    return mRenderThread.queue().runSync([&]() -> auto {
        std::lock_guard lock(mRenderThread.globalProfileData().getDataMutex());
        return mRenderThread.globalProfileData()->findPercentile(percentile);
    });
}

void RenderProxy::dumpGraphicsMemory(int fd, bool includeProfileData, bool resetProfile) {
    if (RenderThread::hasInstance()) {
        auto& thread = RenderThread::getInstance();
        thread.queue().runSync([&]() {
            thread.dumpGraphicsMemory(fd, includeProfileData);
            if (resetProfile) {
                thread.globalProfileData()->reset();
            }
        });
    }
#ifdef __ANDROID__
    if (!Properties::isolatedProcess) {
        std::string grallocInfo;
        GraphicBufferAllocator::getInstance().dump(grallocInfo);
        dprintf(fd, "%s\n", grallocInfo.c_str());
    }
#endif
}

void RenderProxy::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
    if (RenderThread::hasInstance()) {
        auto& thread = RenderThread::getInstance();
        thread.queue().runSync([&]() { thread.getMemoryUsage(cpuUsage, gpuUsage); });
    }
}

void RenderProxy::setProcessStatsBuffer(int fd) {
    auto& rt = RenderThread::getInstance();
    rt.queue().post([&rt, fd = dup(fd)]() {
        rt.globalProfileData().switchStorageToAshmem(fd);
        close(fd);
    });
}

void RenderProxy::rotateProcessStatsBuffer() {
    auto& rt = RenderThread::getInstance();
    rt.queue().post([&rt]() { rt.globalProfileData().rotateStorage(); });
}

int RenderProxy::getRenderThreadTid() {
#ifdef __ANDROID__
    return mRenderThread.getTid();
#else
    return 0;
#endif
}

void RenderProxy::addRenderNode(RenderNode* node, bool placeFront) {
    mRenderThread.queue().post([=, this]() { mContext->addRenderNode(node, placeFront); });
}

void RenderProxy::removeRenderNode(RenderNode* node) {
    mRenderThread.queue().post([=, this]() { mContext->removeRenderNode(node); });
}

void RenderProxy::drawRenderNode(RenderNode* node) {
    mRenderThread.queue().runSync([=, this]() { mContext->prepareAndDraw(node); });
}

void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) {
    mDrawFrameTask.setContentDrawBounds(left, top, right, bottom);
}

void RenderProxy::setHardwareBufferRenderParams(const HardwareBufferRenderParams& params) {
    mDrawFrameTask.setHardwareBufferRenderParams(params);
}

void RenderProxy::setPictureCapturedCallback(
        const std::function<void(sk_sp<SkPicture>&&)>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}

void RenderProxy::setASurfaceTransactionCallback(
        const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
}

void RenderProxy::setPrepareSurfaceControlForWebviewCallback(
        const std::function<void()>& callback) {
    mRenderThread.queue().post(
            [this, cb = callback]() { mContext->setPrepareSurfaceControlForWebviewCallback(cb); });
}

void RenderProxy::setFrameCallback(
        std::function<std::function<void(bool)>(int32_t, int64_t)>&& callback) {
    mDrawFrameTask.setFrameCallback(std::move(callback));
}

void RenderProxy::setFrameCommitCallback(std::function<void(bool)>&& callback) {
    mDrawFrameTask.setFrameCommitCallback(std::move(callback));
}

void RenderProxy::setFrameCompleteCallback(std::function<void()>&& callback) {
    mDrawFrameTask.setFrameCompleteCallback(std::move(callback));
}

void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
        mContext->addFrameMetricsObserver(observer.get());
    });
}

void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
    mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
        mContext->removeFrameMetricsObserver(observer.get());
    });
}

void RenderProxy::setForceDark(ForceDarkType type) {
    mRenderThread.queue().post([this, type]() { mContext->setForceDark(type); });
}

void RenderProxy::copySurfaceInto(ANativeWindow* window, std::shared_ptr<CopyRequest>&& request) {
    auto& thread = RenderThread::getInstance();
    ANativeWindow_acquire(window);
    thread.queue().post([&thread, window, request = std::move(request)] {
        thread.readback().copySurfaceInto(window, request);
        ANativeWindow_release(window);
    });
}

void RenderProxy::prepareToDraw(Bitmap& bitmap) {
    // If we haven't spun up a hardware accelerated window yet, there's no
    // point in precaching these bitmaps as it can't impact jank.
    // We also don't know if we even will spin up a hardware-accelerated
    // window or not.
    if (!RenderThread::hasInstance()) return;
    RenderThread* renderThread = &RenderThread::getInstance();
    bitmap.ref();
    auto task = [renderThread, &bitmap]() {
        CanvasContext::prepareToDraw(*renderThread, &bitmap);
        bitmap.unref();
    };
    nsecs_t lastVsync = renderThread->timeLord().latestVsync();
    nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos();
    nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(SYSTEM_TIME_MONOTONIC);
    // We expect the UI thread to take 4ms and for RT to be active from VSYNC+4ms to
    // VSYNC+12ms or so, so aim for the gap during which RT is expected to
    // be idle
    // TODO: Make this concept a first-class supported thing? RT could use
    // knowledge of pending draws to better schedule this task
    if (timeToNextVsync > -6_ms && timeToNextVsync < 1_ms) {
        renderThread->queue().postAt(estimatedNextVsync + 8_ms, task);
    } else {
        renderThread->queue().post(task);
    }
}

int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
    ATRACE_NAME("HardwareBitmap readback");
    RenderThread& thread = RenderThread::getInstance();
    if (RenderThread::isCurrent()) {
        // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
        return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap);
    } else {
        return thread.queue().runSync(
                [&]() -> int { return (int)thread.readback().copyHWBitmapInto(hwBitmap, bitmap); });
    }
}

int RenderProxy::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) {
    RenderThread& thread = RenderThread::getInstance();
    if (RenderThread::isCurrent()) {
        // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
        return (int)thread.readback().copyImageInto(image, bitmap);
    } else {
        return thread.queue().runSync(
                [&]() -> int { return (int)thread.readback().copyImageInto(image, bitmap); });
    }
}

void RenderProxy::disableVsync() {
    Properties::disableVsync = true;
}

void RenderProxy::preload() {
    // Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
    auto& thread = RenderThread::getInstance();
    thread.queue().post([&thread]() { thread.preload(); });
}

void RenderProxy::setRtAnimationsEnabled(bool enabled) {
    if (RenderThread::hasInstance()) {
        RenderThread::getInstance().queue().post(
                [enabled]() { Properties::enableRTAnimations = enabled; });
    } else {
        Properties::enableRTAnimations = enabled;
    }
}

} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
